Arun Doss
Arun Doss

Reputation: 65

Trigger an apple script / automator when an application comes to focus in mac

I want to automate the keyboard layout based on the application. I am using an Windows VM over remote I wan't to create a script which can:

  1. Change the Keyboard layout when the application switches to Windows VM
  2. Change it back to normal layout with all other apps.

I have hard time finding a trigger event on application focus change. Is it possible to do it over automator?

Or else kindly suggest another solution to resolve the issue.

Upvotes: 4

Views: 3374

Answers (1)

Ted Wrigley
Ted Wrigley

Reputation: 3194

Assuming that you only have two keyboard layouts, you can use the following script application.

First, you'll need to open System Preferences and look at Keyboard➔Shortcuts➔Input Sources; see what the what the keyboard shortcut for 'selecting previous input source' is, make sure it's clicked on, and copy it into the script at the marked places. I have mine set to comd-ctrl-space (^⌘ ), but yours is likely different. You should also check that "Windows VM" is the correct name for the app: find the application in the Finder, select it and type ⌘I to open a Get Info window, and look in the Name & Extension text box.

Now do the following

  1. Copy the following script in the Script Editor
  2. Save it as a stay-open application
    • select 'Application' from the 'Format' menu at the bottom left
    • click the 'Stay open after run handler' checkbox
  3. Open System Preferences and do the following
    • add the app to the Accessibility section in Security & Privacy➔Privacy (so it can send keyboard shortcuts)
    • add the app to the Login Items section for your account in Users & Groups (so it starts automatically at login)

You can then run it and test it out. The app waits in the background to receive notifications that an app has activated or deactivated, then it checks the app name and triggers the keyboard shortcut for the switching the input source when the Window VM app comes or goes.

use AppleScript version "2.4"
use framework "AppKit"
use scripting additions

property NSWorkspace : class "NSWorkspace"

on run
    set workSp to NSWorkspace's sharedWorkspace()
    set notifCent to workSp's notificationCenter()
    tell notifCent to addObserver:me selector:"appHasActivated:" |name|:"NSWorkspaceDidActivateApplicationNotification" object:(missing value)
    tell notifCent to addObserver:me selector:"appHasDeactivated:" |name|:"NSWorkspaceDidDeactivateApplicationNotification" object:(missing value)
end run

on idle
    -- we don't use the idle loop, so tell the system to check in once an hour
    return 3600
end idle

on appHasActivated:notif
    set targetApp to (notif's userInfo's valueForKey:"NSWorkspaceApplicationKey")
    set targetAppName to (targetApp's localizedName) as text
    if targetAppName is "Windows VM" then
        tell application "System Events"
            tell process "Windows VM"
                -- change this line to match your 'Select previous input source' keyboard shortcut
                keystroke space using {command down, control down}
            end tell
        end tell
    end if
end appHasActivated:

on appHasDeactivated:notif
    set targetApp to (notif's userInfo's valueForKey:"NSWorkspaceApplicationKey")
    set targetAppName to (targetApp's localizedName) as text
    if targetAppName is "Windows VM" then
        tell application "System Events"
            tell process targetAppName
                -- change this line to match your 'Select previous input source' keyboard shortcut
                keystroke space using {command down, control down}
            end tell
        end tell
    end if
end appHasDeactivated:

Once you are satisfied it works, you can run the following command in terminal:

defaults write '/path/to/$name.app/Contents/Info.plist' LSUIElement -bool yes

This will turn the app into a background agent, which never takes the foreground and is invisible in the dock. That way you can just forget about it.

Upvotes: 5

Related Questions