1 votos

Cómo crear un nuevo iTerm2 con una tecla y llevar solo esta ventana al frente

He buscado durante bastante tiempo, he hablado con numerosas inteligencias artificiales, inteligencias reales y he probado muchas cosas, incluido el script de Apple y la API de Python de iTerms. Pero me parece imposible lograr esto.

TLDR

Quiero usar un atajo de teclado para abrir una nueva ventana de iTerm (o Terminal) que tenga el foco sin traer todas las ventanas existentes de iTerm (o Terminal) al frente.

No me importa si esta solución es para Terminal o iTerm2, para ser honesto, aunque parece que me gusta iTerm2.

La larga historia

Caso de uso

Imagina que tengo 5 ventanas de iTerm y Safari abiertos en una sola pantalla. Ahora necesito rápidamente otra ventana de iTerm para hacer algo, pero no quiero que las otras ventanas de iTerm ensucien Safari, porque quiero echar un vistazo a la página web al mismo tiempo que escribo en la terminal.

Información del sistema

Estoy en un Mac M3 Pro macOS Sonoma 14.5 iTerm2 Build 3.5.1

Estado actual

Actualmente estoy usando un script de Python que utiliza la API de Python de iTerm para crear una nueva ventana. Esto funciona. Desafortunadamente, esta ventana no viene al frente y no tiene el foco. Siempre es la segunda ventana o aplicación en la que se enfoca actualmente. Uso Hammerspoon para ejecutar el script. El script es complicado, porque probé diferentes soluciones.

El script

#!/usr/bin/python3
import iterm2

import subprocess
import asyncio

def focus_window_applescript(window_id):
    script = f"""
    tell application "iTerm2"
        set id_list to every window's id
        set wnd_id to first item of id_list
        # echo windows
        set newWindow to (first window whose id is wnd_id)
        select newWindow
        # activate
    end tell
    """
    subprocess.run(["osascript", "-e", script])

def focus_window_applescript_2(window_id):
    script = f"""
    tell application "iTerm2"
        -- Ensure we have windows available
        set id_list to every window's id
        set wnd_id to first item of id_list
        set wnd to first window whose id is wnd_id
        set wnd2 to first window
    end tell
    tell application "System Events"
        tell process "iTerm2"
            -- Ensure we have windows available
            #     set frontmost to true
            set index of wnd to 1
            perform action "AXRaise" of first window
        end tell
    end tell
    """
    subprocess.run(["osascript", "-e", script])

def focus_window_applescript_3(wnd_id):
    script = f"""
    tell application "iTerm2"
        # set id_list to every window's id
        # set wnd_id to first item of id_list
        # set wnd to first window whose id is wnd_id
        set wnd to first window
    end tell

    tell application "System Events"
        tell application process "iTerm2"
            # set oWin2 to first window whose name is winTitle
            set focused of wnd to true
            tell wnd to perform action "AXRaise"
        end tell
    end tell
    """

async def main(connection):
    app = await iterm2.async_get_app(connection)
    wnd = await app.windows[-1].async_create(connection)
    await wnd.async_activate()

    print(wnd)

    focus_window_applescript_3(wnd.window_id)

def is_iterm_running():
    try:
        output = subprocess.check_output(["pgrep", "iTerm2"])
        return bool(output.strip())
    except subprocess.CalledProcessError:
        return False

def check_focus_and_create_window():
    script = """
    tell application "System Events"
        set frontmostApplication to name of first application process whose frontmost is true
    end tell

    if frontmostApplication is "iTerm2" then
        tell application "iTerm2"
            create window with default profile
        end tell
        return "true"
    else
        return "false"
    end if
    """
    result = subprocess.run(["osascript", "-e", script], capture_output=True, text=True)
    return result.stdout.strip() == "true"

if __name__ == "__main__":
    if check_focus_and_create_window():
        exit(True)
    if not is_iterm_running():
        subprocess.Popen(["/Applications/iTerm.app/Contents/MacOS/iTerm2"])
        # Wait for iTerm2 to start up
        # for i in range(5):
        #     print("sleep 1")
        #     sleep(1)  # Adjust sleep duration if necessary
    iterm2.run_until_complete(main)
    exit(True)

# async def main(connection):
#   app = await iterm2.async_get_app(connection)
#   print(app.windows)
#   await app.windows[0].async_create(connection)

# iterm2.run_until_complete(main)

Soy nuevo en Mac y estaba usando Arch Linux con Gnome antes. Allí era súper fácil lograr esto :(

Soy consciente de que puede haber un estilo de trabajo diferente para solucionar mis demandas, pero adaptar el estilo de trabajo sería el último recurso.

Se agradece cualquier consejo

Gracias de antemano

1voto

hym3242 Puntos 31

Ten en cuenta que, en Terminal.app, si creas una nueva ventana con un clic derecho en el icono del dock, lograrás lo que deseas. Por lo tanto, puedes escribir un AppleScript que utilice marcos de accesibilidad para acceder al menú de clic derecho del icono del dock. Consulta Applescript click dock item and trigger a menu item para más detalles. Luego guárdalo como un servicio y asígnale un atajo global.

Por supuesto, existen métodos más avanzados, como obtener el wid (windowid) de la nueva ventana y utilizar métodos privados de SkyLight para solo llevarla (y la aplicación) al frente. Pero eso es demasiado hacky y no existe una implementación de código abierto hasta donde yo sé. Yabai tiene una implementación de eso (no muy bien explicada) en window_manager_make_key_window. Si eres bueno en programación, esta es la forma más universal de hacerlo.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X