Mimsy Were the Borogoves

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

42 Astoundingly Useful Scripts and Automations for the Macintosh

Work faster and more reliably. Use Perl, Python, AppleScript, Swift, and Automator to automate the drudgery of computer use. Add actions to the services menu and the menu bar, and create drag-and-drop apps.

Use simple scripts and make your Macintosh play music, roll dice, and talk to you. Create ASCII art from your photos. There’s a script for all of that in my new book, 42 Astoundingly Useful Scripts and Automations for the Macintosh.

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 ->