53

I've got a problem with some app on my Mac stealing the keyboard focus (the current window's title bar becomes inactive). However, it is not actually putting up any windows or menu bar of its own, and it does not respond identifiably to keyboard shortcuts.

Is there a way to determine what application has the keyboard focus even if it is one of those which has no menu bar or Dock icon? I know of one built-in feature that almost does this; the Force Quit dialog, if invoked from the keyboard, will open with the focused application selected. However, it only lists normal has-a-dock-icon applications, so it doesn't help in this case.

This started occurring around the time when I upgraded from 10.8 to 10.9; I suspect that one of the apps I already had installed, or upgraded along with the OS, is newly misbehaving.

I am open to solutions involving a small amount of programming (or AppleScript, say), use of developer tools, etc.; but not ones like “Uninstall things until it goes away” because that would be excessively disruptive at the moment. I'd like to definitively identify the application and file a bug report or fix its configuration.

My research has only turned up a couple of threads requesting the same on Apple Support Communities which did not contain an answer.

1
  • I'm seeing this too. 10.9.4. Perhaps sharing the main apps I have running might highlight a commonality? Chrome, Firefox, Safari, Wuala, Dropbox, Nitrous, 1Password, Google Hangouts, Evernote, Skitch, Google drive, Time Machine, Airport Base Station Agent, Android File Transfer Agent. Otherwise... no easy solution that I know. My suspicion is G Hangouts.
    – JezC
    Commented Sep 7, 2014 at 7:21

6 Answers 6

47

You can find the app that steals focus by saving the following code in a find_focus_stealer.py file and running it via python find_focus_stealer.py in a terminal.

Start running the script – it will print out the name of the active app every 3 seconds. Keep working as usual, wait for the problem to occur, and after a few seconds see the output in the terminal. You’ll have your culprit.

In my case it was a Symantec Antivirus background app (SymUIAgent.app).

#!/usr/bin/python

from AppKit import NSWorkspace
import time
t = range(1,100)
for i in t:
    time.sleep(3)
    activeAppName = NSWorkspace.sharedWorkspace().activeApplication()['NSApplicationName']
    print activeAppName

Credits to iMichael_ in this Apple Discussions thread.

10
  • 4
    This python program worked great, but I had to use the Apple Installed Python. I had brew installed Python 2.7.8 and the AppKit module is not included. Also on my machine the offending app was: SymUIAgent.app Symantec Quick Menu. Commented Dec 17, 2014 at 19:18
  • 2
    @Diodeus the reason why this exits is not because the app that stole focused ended it, but because this was written to only run for a period of 100 seconds. To make it run until I press Ctrl+c in that terminal window I changed for i in t: to be while 1: Commented Jan 28, 2015 at 19:29
  • 2
    Nice! For me, it was Google Drive.app. I did a slight update to your script which I'll post in a separate answer. Thanks!
    – medmunds
    Commented Feb 6, 2015 at 0:36
  • 3
    if you encounter no module named appkit, then run easy_install pip and pip install pyobjc. For me it was Google Drive stealing my focus
    – mihai
    Commented Sep 19, 2016 at 23:33
  • 1
    You have a probelem with the code: for python3 it should be print(activeAppName). also you should run "pip install pyobjc" to install the needed package
    – Ori Wiesel
    Commented May 16, 2023 at 12:19
34

Here’s a slight update to @Ace’s script that runs until you kill it and only prints the app name when it changes. Again, save this code in a file find_focus_stealer.py and then try running it with python find_focus_stealer.py.

#!/usr/bin/python                                                                                                       

try:
    from AppKit import NSWorkspace
except ImportError:
    print "Can't import AppKit -- maybe you're running python from brew?"
    print "Try running with Apple's /usr/bin/python instead."
    exit(1)

from datetime import datetime
from time import sleep

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']
        )
    sleep(1)

I was able to use this to track down “Google Drive” as the focus-stealing culprit on my Mac.

4
  • Good show, Sir! Commented Sep 11, 2015 at 17:11
  • 1
    This worked for me. In my case the focus-stealing app was BetterTouchTool version 2.636. Commented Oct 5, 2018 at 14:46
  • @RoryO'Kane did you figure out how to prevent BetterTouchTool from stealing focus? Commented May 12, 2021 at 2:48
  • 1
    @SanjivJivan Sorry, I don’t remember whether I ever fixed BetterTouchTool’s focus-stealing before I stopped using it. (After I grew annoyed with BTT’s limitations, I set the Touch Bar to show just an Expanded Control Strip and ported my custom actions to Keyboard Maestro.) Commented May 25, 2021 at 1:56
8

Here is improved version of script mentioned in @Ace’s answer:

#!/usr/bin/python
# Prints current window focus.
# See: https://apple.stackexchange.com/q/123730
from AppKit import NSWorkspace
import time
workspace = NSWorkspace.sharedWorkspace()
active_app = workspace.activeApplication()['NSApplicationName']
print('Active focus: ' + active_app)
while True:
    time.sleep(1)
    prev_app = active_app
    active_app = workspace.activeApplication()['NSApplicationName']
    if prev_app != active_app:
        print('Focus changed to: ' + active_app)

It will print the name of the active application that has the focus and will detect if it changed by checking every second.

Related script: Identify which app or process is stealing focus on OSX at Gist

Usage:

  1. Save the above script into a file get_active_focus.py.
  2. Assign execution attributes with the chmod +x get_active_focus.py command.
  3. Run the file with ./get_active_focus.py.

Output:

$ ./get_active_focus.py
Active focus: Terminal
Focus changed to: Google Chrome
2
  • 1
    FWIW this script worked for me where others didn't, and my focus was being stolen by Corel's buggy antipiracy program for CorelDraw.
    – Avery
    Commented Jan 26, 2020 at 0:22
  • I have Python 3 installed via Homebrew and this script worked for me. Had to run it with python3 get_active_focus.py but before I had to install PyObjC via pip3 install -U PyObjC as described here. Commented Sep 14, 2023 at 9:05
6

While it isn't the primary purpose of this application, Karabiner-Elements (a tool for selectively remapping the keyboard) has a focus-change event log which will tell you which application has been stealing focus. While its intended purpose is to set up per-application keyboard mappings, it also has the nice side effect of telling you when a misbehaving app is making things difficult, and I have used it to track down several problem applications.

The method that Karabiner-Elements uses also works better with applications which steal the focus and immediately give it back (unlike the various Python scripts posted in other answers, which can only reliably log focus steals that last for more than one second).

1
  • OK, it's apparently in Karabiner-EventViewer under "Frontmost Application" and only works when open, but cool! Commented Feb 6, 2023 at 18:57
2

For those coming here looking for a solution to use with python3:

Based on @medmund's answer, comments under it as well as https://alexn.org/wiki/macos/#find-which-app-is-stealing-focus

Requirements

  • Python 3 installed and in $PATH
  • Depending on your environment, you may need to substitute python with python3 and pip with pip3.

Usage

Install pyobj

pip install pyobjc

Create python script

With the contents below. Save to new .py file, for this answer I'll use find-focus-stealer.py.

#!/usr/bin/python3

from AppKit import NSWorkspace
from datetime import datetime
from time import sleep

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('{}: {} [{}]'.format(
            datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            active_app['NSApplicationName'],
            active_app['NSApplicationPath']
        ))
    sleep(1)

Run script

From command line, run:

python find-focus-stealer.py

Notes

In my case the issue disappeared after restarting the computer. Though it seems likely that it had to do with Logitech's G HUB as was mentioned elsewhere.

0

Perhaps checking Activity Monitor for active processes? Anything in App Nap state could easily be ruled out, and it might make the hunt a lot shorter.

1
  • Yes, that would be a way of informing a guess about what the problem is, but I'm looking for something that actually obtains the information directly.
    – Kevin Reid
    Commented Mar 9, 2014 at 20:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .