Wechseln Sie mit AppleScript zu einer bestimmten Eingabequelle in OS X in Catalina

Ich verwende verschiedene Tastaturlayouts und wechsele zwischen ihnen mit einem einfachen Skript

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")

Das hat bis zum letzten Update gut funktioniert. Ich spreche nicht wirklich AppleScript, aber ein bisschen Testen zeigt, dass SystemUIServer keinen Zugriff mehr auf einen Menüpunkt mit dem Namen "Texteingabe" hat. Versuchen

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

gibt mir Siri, blutooth, time machine, clockund ein paar anderen. Also wird das Eingabequellenmenü jetzt irgendwie anders verwaltet, aber ich habe jetzt eine Ahnung, wie oder wie ich das herausfinden kann (alle Suchen haben mich auf ähnliche Skripte wie meine verwiesen).

Aktualisierung 10.12.2019

Die bisher vorgeschlagenen Lösungen haben beide Mängel, in einem Fall kommt es immer zu einer Verzögerung von 5 Sekunden, was ziemlich lang ist, und der Trick mit dem Beenden von "System Events", wie aus dem anderen Beitrag entnommen, scheint nicht immer zu funktionieren, manchmal ergibt er sich im Skript ein Timeout (was noch schlimmer ist, als die ganze Zeit die 5 Sekunden Verzögerung zu haben), also sieht es so aus, als ob dies noch eine bessere Lösung benötigt

Antworten (5)

Ich bin auf das gleiche Problem gestoßen, dass ich schnell zwischen mehreren Eingabequellen mit Tastaturkürzeln wechseln wollte, da Catalina die alte Methode mit AppleScript durchbrochen hat. Obwohl die oben genannten Methoden funktionieren, sind sie ziemlich klobig, unzuverlässig und langsam (zumindest für mich).

Nach einigem Suchen im Internet habe ich eine bessere Lösung gefunden. Jemand hat ein Terminal-/Befehlszeilen-Hilfsprogramm geschrieben, das Eingabequellen-Layouts nach Namen ändert, das wirklich gut funktioniert, und Eingabequellen sofort ändert (in Catalina getestet).

Hier sind die Schritte, damit es funktioniert:

  1. Laden Sie die Quelldateien von https://github.com/minoki/InputSourceSelector herunter - klicken Sie auf die grüne Schaltfläche Code → Download ZIP
  2. Extrahieren Sie die ZIP-Datei
  3. Öffnen Sie das Terminal und navigieren Sie zum entpackten Ordner
  4. Führen Sie den makeBefehl in diesem Ordner aus, und eine ausführbare Datei „InputSourceSelector“ wird erstellt. (Möglicherweise müssen Sie über ausführbare Berechtigungen hinzufügen chmod +x InputSourceSelector).

Jetzt können Sie Eingangsquellen mit diesen Befehlen auflisten und wechseln:

  • ./InputSourceSelector list-enabled- um alle derzeit aktivierten Eingangsquellen aufzulisten
  • ./InputSourceSelector current- um die aktuell ausgewählte Eingangsquellen-ID anzuzeigen
  • ./InputSourceSelector select <InputSourceId>- Wechseln zu einer Eingangsquelle anhand ihrer ID

Weitere Befehle finden Sie in der README-Datei auf der Seite des Autors.

Verwenden Sie dann zum Wechseln des Layouts den Befehl „select“ mit einem <InputSourceId>:

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

Das <InputSourceId>ist die ID vor den Klammern, zum Beispiel:

  • Für „com.apple.keylayout.US (US)“ lautet die ID „com.apple.keylayout.US“
  • Für "com.apple.keylayout.Dvorak (Dvorak)" lautet die ID "com.apple.keylayout.Dvorak".
  • Für "com.apple.keylayout.Spanish (Spanisch)" lautet die ID "com.apple.keylayout.Spanish".

IDs mit Leerzeichen müssen Sie möglicherweise in doppelte Anführungszeichen setzen.

Sie können die ausführbare Datei jetzt in „/usr/local/bin“ ablegen, um sie systemweit verfügbar zu machen, und den Befehl ohne das vorangestellte „./“ von überall im System ausführen.

Sie können auch ein paar Verknüpfungen erstellen, um schnell zwischen den verschiedenen Eingabequellen in BetterTouchTool oder einem ähnlichen Programm zu wechseln.

Fügen Sie in BetterTouchTool einfach eine globale Tastenkombination hinzu und wählen Sie für die zugewiesene Aktion "Terminalbefehl ausführen". Verwenden Sie im Terminal-Befehlsfenster den Befehl /usr/local/bin/InputSourceSelector select com.apple.keylayout.Dvorakoder die Eingabequelle, zu der Sie wechseln möchten.

perfekt, funktioniert wie ein Zauber!
Muss ich etwas anderes tun, damit es in einem Shell-Skript funktioniert? Es ist ein großartiges Tool, so viel schneller als Applescript und es funktioniert systemweit in der Terminal-Shell, aber wenn ich versuche, es von einer .sh-Datei auszuführen, tut es trotz des 'x'-Flags nichts.

Leider haben sich die Dinge in macOS Catalina geändert und Sie müssen dieses Menü auf andere Weise aktivieren.

Der folgende Beispiel -AppleScript- Code , der weiter unten gezeigt wird, funktioniert für mich in macOS Catalina , aber da ich in einer virtuellen Maschine getestet habe, weiß ich nicht, ob die Zeitverzögerung bei der Ausführung des Codes zwischen dem Klicken auf das Zielmenü und dem nachfolgenden Code liegt , ist ein Problem in der virtuellen Maschine oder auf einer physischen Maschine.

Ich habe kein deutsches LaTeX2, also habe ich stattdessen Deutsch verwendet, obwohl ich es der Einfachheit halber nach dem Testen im Code ersetzt habe .

Für die Verwendung gelten die üblichen Einschränkungen unter: Systemeinstellungen > Sicherheit & Datenschutz > Datenschutz > Zugänglichkeit

Beispiel AppleScript -Code :

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

Dies macht dasselbe auf eine andere Weise, und eine dieser Methoden kann schneller sein.

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

So verwenden Sie den AppleScript- Beispielcode in einem Handler :

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

Oder die zweite Version des Codes :

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

Hinweis: Der Beispiel -AppleScript- Code ist genau das und enthält keine Fehlerbehandlung , wie es angebracht sein könnte. Es obliegt dem Benutzer, eine Fehlerbehandlung hinzuzufügen, die angemessen, erforderlich oder gewünscht ist. Sehen Sie sich die try- Anweisung und die error- Anweisung im AppleScript Language Guide an . Siehe auch Arbeiten mit Fehlern .

Danke. Die erste Version funktioniert bei mir, die zweite funktioniert bei mir nicht, da ich mehrere Elemente in der Liste habe, die mit "g" beginnen. Die Verzögerung tritt auch auf einer physischen Maschine auf. und es ist lang (5 Sekunden?) Aber ich habe diese Antwort hier gefunden apple.stackexchange.com/a/92386 was hilft, wenn ich es mit Ihrem kombiniere, dh es funktioniert ohne Hängen.
@Frank Mittelbach, Obwohl ich dies im Moment nicht brauche, da alle aktuellen Skripte, die ich verwende, nicht anfällig für diesen Fehler sind, habe ich dennoch eine Kopie der verlinkten Webseite für zukünftige Referenzzwecke gespeichert. BTW Es hat es auch in der virtuellen Maschine fast augenblicklich gemacht. Danke!

Fürs Protokoll, wenn Sie die Antwort, wie Sie in Catalina zum Eingabequellenmenü gelangen, mit einer Antwort kombinieren, die sich mit dem Fehler (?) befasst, der eine Verzögerung erzeugt, erhalten Sie eine Version, die genauso gut funktioniert wie die alte:

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")

Aktualisierung 10.12.2019

Der Trick mit dem Töten von "System Events" aus dem anderen Posting scheint nicht immer zu funktionieren, manchmal führt es dazu, dass das Skript eine Zeitüberschreitung erhält (was noch schlimmer ist, als die ganze Zeit über 5 Sekunden Verzögerung zu haben), so wie es aussieht als ob die Lösung meiner Frage noch etwas offen ist

Ich habe dieses Skript vor einiger Zeit geschrieben, das eine Kohlenstoff-API verwendet, um die Tastatureingabequelle durch Systemaufrufe auf niedriger Ebene zu ändern, was normalerweise ideal und offensichtlich der Manipulation der Benutzeroberfläche vorzuziehen wäre. Allerdings ist es ein paar Jahre alt, und daher kann ich nicht sagen, ob es in Catalina noch brauchbar sein wird, nicht zuletzt, weil Carbon veraltet ist (oder ist), aber das Skript ist in JavaScript for Automation geschrieben , das wie AppleScript im Grunde in Stücke zerfällt.

Aber ich werde es trotzdem posten, nur für den Fall, dass es in der neueren Betriebssystemeinstellung einen Wert hat:

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);
}
Es stürzt den auf JavaScript eingestellten Skripteditor unter macOS Catalina 10.15.1 ab, ohne die Eingabesprache zu ändern.
@ user3439894 Das ist schade, aber überhaupt nicht überraschend. Der JavaScriptOSAKern wurde einfach dem Verfall überlassen, obwohl es die Ziel-C-Brücke ist, die meiner Meinung nach bröckelt, da die Abstürze in Mojave begannen, wenn die OSAEngine versuchte, zu/von C-Stil-Referenzen zu überbrücken. Ich habe es auch in Swift geschrieben, das ich irgendwo habe, es sei denn, ich habe es auf meinem MacBook gelassen, bevor es zur Reparatur ging.

Ich habe eine alternative Lösung gefunden, die keine Verzögerung garantiert, indem ich die systemweite Tastenkombination ^ F8 verwende (vordefiniert in "Systemeinstellungen> Tastatur> Tastenkombinationen> Tastatur> Fokus auf Statusmenüs verschieben").

kombiniert mit der gewünschten Anzahl von Pfeiltasten nach unten und einem Return, funktioniert wie ein Zauber

Ich wünschte, das Obige sieht für Sie wie AppleScript aus, Tatsache ist, dass ich nach Jahren der Verwendung immer noch nicht das einfachste AppleScript schreiben kann.

Also habe ich die obige Reihe von Tastenanschlägen in BetterTouchTool definiert, es macht den Job :)

BetterTouchTool-Screenshot