Cambie a una fuente de entrada específica en OS X en Catalina con AppleScript

Utilizo diferentes diseños de teclado y cambié entre ellos usando un script simple

on changeKeyboardLayout(layoutName)
    tell application "System Events" to tell process "SystemUIServer"
        tell (1st menu bar item of menu bar 1 whose description is "text input") to {click, click (menu 1's menu item layoutName)}
    end tell
end changeKeyboardLayout
changeKeyboardLayout("German LaTeX2")

Eso funcionó bien hasta la última actualización. Realmente no hablo AppleScript, pero un poco de prueba indica que SystemUIServer ya no tiene acceso a un elemento de menú con el nombre "entrada de texto". Intentando

tell application "System Events" to tell process "SystemUIServer" to get value of attribute "AXDescription" of every menu bar item of menu bar 1

me da Siri, blutooth, time machine, clocky algunos otros. Entonces, de alguna manera, el menú de la fuente de entrada se administra de manera diferente ahora, pero ahora tengo una idea de cómo o cómo averiguarlo (todas las búsquedas me señalaron scripts similares al mío)

Actualización 2019/12/10

Las soluciones sugeridas hasta ahora tienen defectos, en un caso, siempre obtiene un retraso de 5 segundos, que es bastante largo y el truco de eliminar los "Eventos del sistema" tomados de la otra publicación no siempre parece funcionar, a veces resulta en el script obteniendo un tiempo de espera (que es aún peor que tener el retraso de 5 segundos todo el tiempo), por lo que parece que todavía se necesita una mejor solución

Respuestas (5)

Me topé con el mismo problema de querer cambiar rápidamente entre múltiples fuentes de entrada con atajos de teclado ya que Catalina rompió el método anterior usando AppleScript. Aunque los métodos anteriores funcionan, son bastante torpes, poco fiables y lentos (al menos para mí).

Después de investigar un poco en Internet, encontré una mejor solución. Alguien escribió un programa de utilidad de línea de comando/terminal que cambia los diseños de las fuentes de entrada por nombre que funciona muy bien y cambia las fuentes de entrada instantáneamente (probado en Catalina).

Estos son los pasos para que funcione:

  1. Descargue los archivos fuente desde https://github.com/minoki/InputSourceSelector - haga clic en el botón verde Código → Descargar ZIP
  2. Extraiga el archivo ZIP
  3. Abra la terminal y navegue a la carpeta descomprimida
  4. Ejecute el makecomando en esa carpeta y se producirá un "InputSourceSelector" ejecutable. (Es posible que deba agregarle permisos ejecutables a través de chmod +x InputSourceSelector).

Ahora puede enumerar y cambiar las fuentes de entrada con estos comandos:

  • ./InputSourceSelector list-enabled- para enumerar todas las fuentes de entrada habilitadas actualmente
  • ./InputSourceSelector current- para mostrar la identificación de la fuente de entrada actualmente seleccionada
  • ./InputSourceSelector select <InputSourceId>- para cambiar a una fuente de entrada por su id

Consulte el LÉAME en la página del autor para obtener más comandos.

Luego, para cambiar los diseños, use el comando 'seleccionar' con un <InputSourceId>:

  • ./InputSourceSelector select com.apple.keylayout.US
  • ./InputSourceSelector select com.apple.keylayout.Dvorak
  • ./InputSourceSelector select com.apple.keylayout.Spanish

El <InputSourceId>es el id antes de los paréntesis, por ejemplo:

  • Para "com.apple.keylayout.US (US)", la identificación es "com.apple.keylayout.US"
  • Para "com.apple.keylayout.Dvorak (Dvorak)", la identificación es "com.apple.keylayout.Dvorak"
  • Para "com.apple.keylayout.Spanish (Español)", la identificación es "com.apple.keylayout.Spanish"

Para identificaciones con espacios, es posible que deba encerrarlos entre comillas dobles.

Ahora puede colocar el archivo ejecutable en '/usr/local/bin' para que esté disponible en todo el sistema y ejecutar el comando sin el './' anterior desde cualquier parte del sistema.

También puede crear un par de atajos para cambiar rápidamente entre las distintas fuentes de entrada en BetterTouchTool o un programa similar.

En BetterTouchTool simplemente agregue un atajo de teclado global y, para la Acción asignada, seleccione "Ejecutar comando de terminal". En la ventana de comandos del terminal, use el comando /usr/local/bin/InputSourceSelector select com.apple.keylayout.Dvorako cualquier fuente de entrada a la que desee cambiar.

perfecto, funciona a las mil maravillas!
¿Necesito hacer algo diferente para que funcione en un script de shell? Es una herramienta increíble, mucho más rápida que AppleScript y funciona bien en todo el sistema en el terminal, pero cuando trato de ejecutarlo desde un .sh no hace nada a pesar de la marca 'x'.

Desafortunadamente, las cosas han cambiado en macOS Catalina y tendrás que activar ese menú de una manera diferente.

El siguiente código AppleScript de ejemplo , que se muestra más abajo, funciona para mí en macOS Catalina , sin embargo, como estaba probando en una máquina virtual, no sé si el tiempo de retraso en la ejecución del código , entre hacer clic en el menú de destino y el código posterior , es inherente a un problema en la máquina virtual o será lo mismo en una máquina física.

No tengo LaTeX2 en alemán , así que usé alemán en su lugar, aunque por conveniencia lo reemplacé en el código después de la prueba.

Se aplican las advertencias habituales para el uso de esto en: Preferencias del sistema > Seguridad y privacidad > Privacidad > Accesibilidad

Ejemplo de código AppleScript :

tell application "System Events" to ¬
    tell application process "TextInputMenuAgent" to ¬
        tell menu bar item 1 of menu bar 2
            click
            click menu item "German LaTeX2" of menu 1
        end tell

Esto hace lo mismo de una manera diferente, y una de estas formas puede ser más rápida.

tell application "System Events" to ¬
    tell application process "TextInputMenuAgent" to ¬
        click menu bar item 1 of menu bar 2

tell application "System Events"
    keystroke "g"
    key code 36
end tell

Para usar el código AppleScript de ejemplo en un controlador :

changeKeyboardLayout("German LaTeX2")

on changeKeyboardLayout(layoutName)
    tell application "System Events" to ¬
        tell application process "TextInputMenuAgent" to ¬
            tell menu bar item 1 of menu bar 2
                click
                click menu item layoutName of menu 1
            end tell
end changeKeyboardLayout

O la segunda versión del código :

changeKeyboardLayout("German LaTeX2")

on changeKeyboardLayout(layoutName)
    tell application "System Events" to ¬
        tell application process "TextInputMenuAgent" to ¬
            click menu bar item 1 of menu bar 2
    tell application "System Events"
        keystroke (first text item of layoutName)
        key code 36
    end tell
end changeKeyboardLayout

Nota: El código AppleScript de ejemplo es solo eso y no contiene ningún manejo de errores que pueda ser apropiado. El usuario tiene la responsabilidad de agregar cualquier manejo de errores que sea apropiado, necesario o deseado. Eche un vistazo a la declaración de prueba y la declaración de error en la Guía del lenguaje AppleScript . Consulte también Trabajar con errores .

gracias. la primera versión me funciona, la segunda no me funciona ya que tengo varios elementos en la lista que comienzan con "g". El retraso también ocurre en una máquina física. y es largo (¿5 segundos?) Pero encontré esta respuesta aquí apple.stackexchange.com/a/92386 que ayuda si lo combino con el tuyo, es decir, entonces funciona sin colgar.
@Frank Mittelbach, aunque en este momento no necesito esto, ya que todos los scripts actuales que uso no son propensos a este error, no obstante, guardé una copia de la página web vinculada para futuras referencias que necesitaba. Por cierto, también lo hizo casi instantáneo en la máquina virtual. ¡Gracias!

Para que conste, combinando la respuesta sobre cómo llegar al menú de fuente de entrada en Catalina con una respuesta que se ocupa del error (?) que genera un retraso , da una versión que funciona tan bien como la anterior:

on changeKeyboardLayout(layoutName)
    launch application "System Events"
    delay 0.2
    ignoring application responses
        tell application "System Events" to tell process "TextInputMenuAgent"
            click menu bar item 1 of menu bar 2
        end tell
    end ignoring
    do shell script "killall System\\ Events"
    delay 0.1
    tell application "System Events" to tell process "TextInputMenuAgent"
        tell menu bar item 1 of menu bar 2
            click menu item layoutName of menu 1
        end tell
    end tell
end changeKeyboardLayout

changeKeyboardLayout("German LaTeX2")

Actualización 2019/12/10

El truco de matar "Eventos del sistema" tomados de la otra publicación no siempre parece funcionar, a veces hace que el script obtenga un tiempo de espera (lo que es aún peor que tener el retraso de 5 segundos todo el tiempo), por lo que parece como si la solución a mi pregunta todavía estuviera algo abierta

Escribí este script hace un tiempo que usa una API de carbono para cambiar la fuente de entrada del teclado a través de llamadas al sistema de bajo nivel, lo que normalmente sería ideal y obviamente preferible a manipular la interfaz de usuario. Dicho esto, tiene un par de años, por lo que no podría decir si seguirá siendo viable en Catalina, sobre todo porque el carbono está (o está) en desuso, pero el script está escrito en JavaScript para automatización. , que, como AppleScript, básicamente se está cayendo a pedazos.

Pero lo publicaré de todos modos, en caso de que tenga valor en la nueva configuración del sistema operativo:

ObjC.import('Carbon');

nil = $();

unwrap = ObjC.deepUnwrap.bind(ObjC);
bind = ObjC.bindFunction.bind(ObjC);
bind('CFMakeCollectable', [ 'id', [ 'void *' ] ]);
Ref.prototype.nsObject = function() {
    return unwrap($.CFMakeCollectable(this));
}


function run() {
    const lang = 'German';

    const currentSource = $.TISCopyCurrentKeyboardInputSource();
    const sources   = unwrap($.TISCreateInputSourceList(nil, false)),
          sourceIDs = sources.map(src => $.TISGetInputSourceProperty(
                                      src,'TISPropertyInputSourceID')
                             .nsObject()),
          sourceID  = sourceIDs.filter(src=>src.indexOf(lang)!==-1)[0],
          source    = unwrap($.TISCreateInputSourceList(
                            { 'TISPropertyInputSourceID' : sourceID },
                      false))[0];
    const status    = $.TISSelectInputSource(source);
    return (status==0);
}
Bloquea el Editor de scripts establecido en JavaScript en macOS Catalina 10.15.1, sin cambiar el idioma de entrada.
@ user3439894 Es una pena, pero no sorprende en absoluto. El JavaScriptOSAnúcleo simplemente se ha dejado descomponer, aunque creo que es el puente del objetivo C el que se está desmoronando, ya que los bloqueos comenzaron en Mojave cada vez que el OSAmotor intentaba conectarse a/desde las referencias de estilo C. También lo escribí en Swift, que tengo en alguna parte, a menos que lo deje en mi MacBook antes de que lo repararan.

Encontré una solución alternativa que garantiza que no haya demoras, utilizando el atajo de teclado de todo el sistema ^F8 (predefinido en "Preferencias del sistema> Teclado> Atajos> Teclado> Mover el enfoque a los menús de estado")

combinado con la cantidad deseada de pulsaciones de teclas de flecha hacia abajo y un Retorno, funciona de maravilla

Deseo que lo anterior se vea como AppleScript para usted, el hecho es que todavía no puedo escribir el AppleScript más simple después de años de usarlo.

Así que definí la serie anterior de pulsaciones de teclas en BetterTouchTool, hace el trabajo :)

Captura de pantalla de BetterTouchTool