PyObjc/AppKit - launch Mac app without stealing focus

295 views Asked by At

I'm not sure if what I want to do is possible. I'm using PyObjc and the iTerm2 API to create a split and send some text. Works great, but I'd like it to not steal focus if the user is doing something else; i.e. don't put iTerm in the foreground if it's not there, already.

What I have, now (also my first ever Python program - be kind):

#!/usr/bin/env python3

'''Upgrade Homebew Casks in a new iTerm2 vertical split'''

import os
import iterm2
import osascript
import AppKit

def get_term_cookie():
    '''
    Launch iTerm and get a security token.

    Get a token from iTerm and store in $ITERM_COOKIE env variable.
    This is required to run iterm API's without a "Do you really trust this program?"
    dialog box from being presented.

    See https://gitlab.com/gnachman/iterm2/-/wikis/iTerm2-Version-3.3-Security-Updates
    '''

    iterm = AppKit.NSWorkspace.sharedWorkspace().launchApplication_("iTerm")
    if not iterm:
        print("Failed to launch iTerm2")
        return False

    ret_code,os.environ["ITERM2_COOKIE"],err = (
        osascript.run('tell application "iTerm2" to request cookie'))

    if os.environ["ITERM2_COOKIE"]:
        return True
    else:
        print("Failed to get a cookie from iTerm")
        print("ret_code: " + ret_code)
        print ("err: " + err)
        return False

async def upgrade_brew_casks(connection):
    '''Connect to iTerm2 and upgrade brew casks.'''

    # get a connection to iTerm app
    app = await iterm2.async_get_app(connection)

    # get the current session and make a new vertical split
    active_session = app.current_terminal_window.current_tab.current_session
    await active_session.async_split_pane(vertical=True)

    # run the cask upgrade in the new split
    new_session = app.current_terminal_window.current_tab.current_session
    await new_session.async_send_text('brew cu -ay --no-brew-update\n')

    # return focus to the original split
    await active_session.async_activate()

    return True

if __name__ == '__main__':
    if get_term_cookie():
        # Passing True for the second parameter means keep trying to
        # connect until the app launches.
        iterm2.run_until_complete(upgrade_brew_casks, True)
0

There are 0 answers