Mimsy Were the Borogoves

Hacks: Articles about programming in Python, Perl, PHP, and whatever else I happen to feel like hacking at.

What app keeps stealing focus?

Jerry Stratton, January 8, 2016

I’ve been having a problem lately on Mac OS X Yosemite, 10.10, with losing focus on the window I’m typing in. Most of the time it didn’t happen often; sometimes it would happen three or four times over several minutes. The screen doesn’t change: the menu bar still tells me I’m in Safari or iA Writer or whatever. But suddenly my typing is going nowhere.

A quick Google search on “Mac OS X application window keeps losing focus” and I found I wasn’t alone. The problem seems to be that some background app is stealing the focus, but since it’s a background app the menu doesn’t change from the current app.

On How do I tell which app stole my focus in OS X?, medmunds provided a neat little Python script for displaying the current active app as soon as the active app changes. It also displays the path to the app so that you know specifically where the offender lies.

I quickly realized that I keep a lot of windows open, and the Terminal window soon disappeared behind all of my working windows. Obviously once I noticed a focus change, I could go back to Terminal to see what it was, but if it happened while I was reading a web page, I might not notice it for a long time—scrolling doesn’t need focus to work.

So I did another search on “Python Mac OS X speak” and found an answer by arainchi that should, and did, allow importing the Mac’s built-in speech synthesizer software. I added a volume reduction (hearing a loud voice announcing the app change every time I switched an app became annoying very quickly) and improved the responsiveness of the script. Mac OS X Python supports fractional sleep times, so I reduced it to two-tenths of a second instead of a whole second.

[toggle code]

  • #!/usr/bin/python
  • try:
    • from AppKit import NSWorkspace, NSSpeechSynthesizer
  • except ImportError:
    • print "Can't import AppKit -- maybe you're running a non-Mac Python?"
    • print "Try running with Apple's /usr/bin/python instead."
    • exit(1)
  • from datetime import datetime
  • from time import sleep
  • speak = NSSpeechSynthesizer.alloc().init()
  • speak.setVolume_(.5)
  • last_active_name = None
  • while True:
    • active_app = NSWorkspace.sharedWorkspace().activeApplication()
    • if active_app['NSApplicationName'] != last_active_name:
      • last_active_name = active_app['NSApplicationName']
      • print '%s: %s [%s]' % (
        • datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
        • active_app['NSApplicationName'],
        • active_app['NSApplicationPath']
      • )
      • speak.startSpeakingString_("Changed to " + active_app['NSApplicationName'])
    • sleep(.2)

After about twenty minutes of working, I discovered that the offending app, or at least one of them, was Google Drive. My Google Drive was about 6 versions out of date; I was running 1.20 and the current version at the time I’m writing this is 1.26. I’ve updated it; I don’t know whether that was the problem or even whether Google Drive was the only offender. If the issue persists, I now have a script to help discover where the problem lies.

  1. <- Pythonista circle
  2. Django-MPTT ->