5

I'm a developer and a long-time Windows user with an obsession about making my system as convenient to use as possible.

Yesterday I thought about something that has always annoyed me in Windows and that I've taken for granted, and I realized that I have a better idea for how it could work, and I'm now wondering whether it's possible to tweak Windows to work like that.

The thing that annoys me is when windows steal focus. For example, I could be running an installer for some program. While it's working, I'll switch to my browser and browse, maybe entering some text into an email in my browser. Then suddenly the installer finishes and its window steals the focus. Now I'm in the middle of writing an email, so I might press a key that happens to be bound to a button on that installer, and then that button gets invoked, doing some action that I never intended to happen!

This is doubly annoying to me because I'm using a multiple-desktop program called DexPot, and when a window steals focus, it also brings itself to the desktop I'm currently on, which can be really annoying, because then I have to put it back into its original desktop.

How my ideal solution to this problem would work: Every time a window tries to steal focus, we intercept that, and don't let it. We show something like a toaster message saying "Foobar installer wants focus, press Win-Whatever to switch to it". If and when you press the key combo, it switches to the window.

The question is: Is there an easy way to tweak Windows to make this happen? I know very little about Windows programming. I do know AHK and if it's possible with that, that'd be great.

Ram Rachum
  • 84,019
  • 84
  • 236
  • 374
  • Focus stealing is somewhat related to security. Starting with Windows Vista, there are already some mechanisms in place to prevent focus stealing. Check this article: http://msdn.microsoft.com/en-us/library/bb756922.aspx (section "Use the HWND Property to Be Acknowledged as a Foreground Application") – Simon Mourier Oct 15 '14 at 21:49

1 Answers1

4

No, there isn't an easy way to add this behavior, but Windows tries to do this automatically.

In theory apps shouldn't be able to steal the foreground while you're actively using another app. Unfortunatly there are some scenarios where Windows can't tell the difference between legitimate user actions that should change the foreground and unwanted foreground-theft. The window manager generally tightens up the holes a bit with each new version of Windows, but also needs to make sure that apps can come to the foreground when the user wants them to, even if that desire is expressed indirectly.

For example, a process launched by the current foreground process can put a window into the foreground. This is necessary so that when a user launches a window from Explorer the newly launched process can open its main window. This permission only lasts until the next user input, so if an application is slow to launch and you start working on an email the app may lose its foreground permissions before it can use them.

See the SetForegroundWindow function documentation for a list of requirements for a process to be able to set a window into the foreground.

There are also apps which specifically make use of these requirements to steal the permission (by joining the foreground queue or synthsising user input to themselves), but I suspect in your installer scenario it is accidental.

I'm not sure what exactly is going on, but I suspect that the problem comes from the installer running as a service and accidentally stealing the foreground permission when it tries to launch the app on your current desktop.

It would be theoretically possible for an external process to hook into the foreground system to override this and show your confirmation toast, but it would be tricky to get right and would require significant low level code (I'd probably start with a CbtHook). It would not be possible in a scripting package like AHK (assuming you mean AutoHotKey) but would need to be native C/C++ code injected into every running process.

Rob Caplan - MSFT
  • 21,714
  • 3
  • 32
  • 54
  • Hmm, I'm not sure that we're talking about the same thing, because, for example, my Python IDE steals the global focus whenever the debugged process stops (whether it's because of an exception or a breakpoint). It puts the window in the foreground and puts global focus on it, and it doesn't involve starting a new process. So how could this be given what you're saying? – Ram Rachum Oct 15 '14 at 19:54
  • See the SetForegroundWindow docs I linked: "The process is being debugged" is one of the allowed exceptions. Otherwise debugging would be very frustrating. – Rob Caplan - MSFT Oct 15 '14 at 22:06
  • Wow, I didn't think that would apply, because (a) it's a Python debugger, not a C one, does Windows still recognize it as a debugger? and (b) the IDE is the one who's stealing the focus, and it's not the debugged process but rather the debugging process. So how could it still steal the focus? – Ram Rachum Oct 16 '14 at 09:52
  • a) If the debugger uses the debugger API then it's a debugger. Windows doesn't care what language it uses. It's also possible that Python has the debugger and the debuggee working together to manage the foreground: the foreground process (debugee) can set or allow any other process' window into the foreground b) if the foreground process is being debugged then anybody can take focus from it. – Rob Caplan - MSFT Oct 16 '14 at 20:43
  • Okay, how about this: I have a text editor EditPad Pro open. It has a tabbed interface so it opens multiple text files in the same window/process. Explorer has the focus, and I'm pressing enter on a text file to have it open in EPP. How come EPP automatically gets global focus, despite it not being a debugger? – Ram Rachum Oct 17 '14 at 10:20
  • To the user this is the same as launching a new process, so Explorer allows EPP foreground access when it hands the launched file information over. Again, see the remarks in the SetForegroundWindow docs. Being a debugger is one of several reasons listed. – Rob Caplan - MSFT Oct 17 '14 at 15:07