Wie können Sie herausfinden, welcher Monitor die Menüleiste in AppleScript hat?

Beim Spielen mit AppleScript möchte ich die Position einiger Fenster manipulieren, positionaber ich habe ein Problem beim Definieren des Monitors. Derzeit habe ich mehrere Monitore unterschiedlicher Größe und Marke, die ich auf meinen Reisen mit meinem MacBook verbinde. Das einzige, was sich bei allen vier Monitoren, mit denen ich verbunden bin, wiederholt, ist, dass der Monitor, den ich bearbeiten möchte, die Menüleiste enthält.

Beim Testen mit do shell script "system_profiler SPDisplaysDataTypebin ich mir nicht sicher, ob der zurückgegebene Text von Main Display: Yesder Ansicht ist, dass sich die Menüleiste aus der Extraktion dort befindet, wo sich die Menüleiste befindet:

Graphics/Displays:

    Intel Iris Pro:

      Chipset Model: Intel Iris Pro
      Type: GPU
      Bus: Built-In
      VRAM (Dynamic, Max): 1536 MB
      Metal: Supported
      Displays:
        Color LCD:
          Display Type: Built-In Retina LCD
          Resolution: 2880 x 1800 Retina
          Mirror: Off
          Online: Yes
          Rotation: Supported
          Automatically Adjust Brightness: Yes
          Connection Type: DisplayPort
        Thunderbolt Display:
          Display Type: LCD
          Resolution: 2560 x 1440
          Main Display: Yes
          Mirror: Off
          Online: Yes
          Rotation: Supported
          Automatically Adjust Brightness: No
          Connection Type: DisplayPort

Wenn meine Annahme Main Displayrichtig ist, wie soll ich die Auflösung der identifizierten Hauptanzeige richtig erfassen, damit ich die Fenster manipulieren kann?

Wenn ich recherchiere, scheint es, dass einige normalerweise einfach in jedes Display treten:

Ich weiß also nicht, ob das zwei Fragen in einer wären. Ich bin etwas verwirrt darüber, wie die Reihenfolge beim Anschließen an mehrere Monitore bestimmt wird (z. B. bin ich heute möglicherweise mit einem Thunderbolt-Display verbunden, aber morgen könnte ich über meine beiden DisplayPorts mit zwei Dells-Monitoren verbunden sein) und ob es eine Möglichkeit gibt Zielen Sie einen Monitor insbesondere basierend auf der Menüleiste an.

Ich kann die App und ihre Größe bereits erkennen mit:

tell application "System Events" to tell application process "Notes" to set theSize to get size of window 1
set theWidth to item 1 of theSize
set theHeight to item 2 of theSize

Aber mein Problem besteht darin, die Auflösung zu bestimmen, damit ich das App-Fenster berechnen positionund boundsverschieben kann.

Antworten (3)

AKTUALISIEREN

Meine ursprüngliche Antwort entfernt. Hier ist ein völlig anderer Ansatz, den ich meiner ursprünglichen Lösung vorziehe. Diese Version verwendet tatsächlich den Skriptzusatz „Image Events“.

Dieses Skript ruft die Namen der an Ihren Computer angeschlossenen Displays ab. Die zurückgegebenen Werte von "Anzeige "Anzeige 1" sind immer "Welcher Monitor hat die Menüleiste in AppleScript?"

property activeDesktop : missing value
property activeDesktopResolution : missing value

set displayNames to {}

tell application "Image Events"
    set theDisplays to displays
    repeat with i from 1 to number of items in theDisplays
        set this_item to item i of theDisplays
        set theName to name of display profile of item i of theDisplays
        set end of displayNames to theName
        set activeDesktop to item 1 of displayNames
    end repeat
end tell

tell application "Finder"
    set activeDesktopResolution to bounds of window of desktop
    set activeDesktopResolution to items 3 thru 4 of activeDesktopResolution
end tell

set theResultz to display dialog activeDesktop & "  " & item 1 of activeDesktopResolution & " x " & item 2 of activeDesktopResolution ¬
    buttons ¬
    "OK" with title ¬
    "Your Current Display and Its Resolution" with icon 1 ¬
    giving up after 10

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

Können Sie bitte erläutern, wie dies für mehrere Monitore funktionieren soll? Bei meinem Doppelmonitor-Setup bounds of window of desktopist das Ergebnis immer das gesamte Rechteck, das beide Displays umfasst, also ergibt eine 1920 x 1080 neben einer 1280 x 800 jedes Mal 3200 x 1080.
In der folgenden Abbildung sehen Sie, dass die rot eingekreiste Menüleiste zwischen verbundenen Displays hin und her bewegt werden kann … in Systemeinstellungen/Displays, wenn die Option „Displays spiegeln“ deaktiviert ist. Unabhängig davon, welche Anzeige die Menüleiste enthält, befindet sie sich in den Anzeigeabmessungen, die der AppleScript-Code zurückgibt. i.imgur.com/vPD5upS.jpg

In meinen Tests haben Sie Recht, dass das Hauptdisplay dasjenige ist, dem das Menü in den Systemeinstellungen von Displays zugewiesen ist. Ich habe getestet, indem ich die Menüleiste von einem Display zum anderen verschoben und Ihr Skript ausgeführt habe. Die Ergebnisse deuten darauf hin, dass, wo auch immer sich die Menüleiste befindet, diese Anzeige "Hauptanzeige: Ja" in ihren Informationen enthält.

Um die Auflösung zu parsen, würde ich das Argument -xml für den Befehl system_profiler verwenden, um einen konsistenten Text zu erhalten, nach dem gesucht werden kann, und dann die Textelement-Trennzeichen von Apple verwenden, um die Daten zu parsen. Ich habe dieses Skript geschrieben, und wenn ich das Menü hin und her schalte, gibt es die Auflösung der aktuellen Hauptanzeige zurück. Möglicherweise müssen Sie die Trennzeichen anpassen, je nachdem, was Ihr Betriebssystem für den System-Profiler-Bericht zurückgibt.

Ich habe im folgenden Code Inline-Kommentare hinzugefügt, um zu erklären, was das Skript tut.

set pfl to do shell script "system_profiler -xml SPDisplaysDataType"

set tid to text item delimiters
set text item delimiters to "</data><key>_name</key>"--in my reports, each display section starts with this xml code

ignoring white space --allows us to not worry about returns, tabs, spaces, etc.
    repeat with i from 2 to count of pfl's text items
        set aDisplay to pfl's text item i
        if aDisplay contains "<key>spdisplays_main</key><string>spdisplays_yes</string>" then--check if this display is the main
            set text item delimiters to "<key>_spdisplays_resolution</key><string>"--this is the xml code for the resolution
            set displayRes to aDisplay's text item 2
            set text item delimiters to "</string"--remove the ending xml code
            set displayRes to displayRes's text item 1
        end if
    end repeat
end ignoring
set text item delimiters to tid --always text text item delimiters back to default
return displayRes

BEARBEITEN: Da Sie oben die reguläre Form des system_profiler gepostet haben, habe ich das Skript neu geschrieben, um diese Ausgabe zu analysieren. Es erscheint mir etwas riskanter als die Verwendung von XML, aber es sollte auf Ihrem System ohne Änderungen korrekt kompiliert und ausgeführt werden.

set pfl to do shell script "system_profiler SPDisplaysDataType"
set tid to text item delimiters
set text item delimiters to "Displays:"
set pfl to text item 3 of pfl
set text item delimiters to "Mirror:"
repeat with i from 1 to count of pfl's text items
    set aDisplay to pfl's text item i
    ignoring white space
        if aDisplay contains "Main Display: Yes" then
            if aDisplay contains "Resolution:" then
                set text item delimiters to "Resolution: "
                set displayRes to text item 2 of aDisplay
                considering white space
                    set text item delimiters to "\r" --line breaks should be \r
                    set displayRes to text item 1 of displayRes
                    set text item delimiters to "\n" --or they might be \n
                    set displayRes to text item 1 of displayRes
                end considering
            end if
        end if
    end ignoring
    set text item delimiters to "Mirror:"
end repeat
set text item delimiters to tid
return displayRes
Wenn ich Ihren Code kopiere und in den Skripteditor einfüge, während er kompiliert wird, tritt dennoch ein Fehler auf. Soll ich etwas an dem von Ihnen geposteten Code ändern, damit es funktioniert, wenn ja, was?
Sie müssten wahrscheinlich den XML-Bericht überprüfen, den er zurückgibt, um sicherzustellen, dass die Dinge, die ich als Trennzeichen für Textelemente festgelegt habe, auf Ihrem System gleich sind. Sie können direkt nach der ersten Codezeile eine Codezeile "return pfl" hinzufügen, um zu sehen, was Ihr System zurückgibt. Wenn beispielsweise "</data><key>_name</key>" in Ihrem Bericht nicht vorhanden ist (ohne Leerzeichen), müssen Sie es in das ändern, was direkt vor dem Namen des Displays steht. Wenn "<key>_spdisplays_resolution</key><string>" nicht existiert, ändern Sie es entsprechend. Ich verwende Sierra 10.12.6, es ist möglich, dass Sie eine dif-Version mit dif-Bericht haben.
Wenn Sie die XML-Datei hier posten möchten (was pfl in diesem Skript ist), suche ich nach den Trennzeichen und überarbeite das Skript, um dies widerzuspiegeln.
Ihre codierte Aktualisierung kehrt mit einem führenden Leerzeichen zurück, z. B. " 2560 x 1440"aber wenn Sie ein Leerzeichen nach hinzufügen Resolution, z. B. set text item delimiters to "Resolution: "es entfernen, z"2560 x 1440"
fügte das Leerzeichen hinzu.

Getestet auf meinem MacBook Pro mit angeschlossenem Thunderbolt-Display und der darauf befindlichen Menüleiste hat Folgendes funktioniert:

set theMainDisplayName to do shell script "system_profiler SPDisplaysDataType | grep -B 5 'Main Display:' | awk '{sub(/^[ \t]+/, \"\"); print $0; exit}'"
return theMainDisplayName

Result:
"Thunderbolt Display:"

Wenn ich die Menüleiste auf das MacBook Pro umschalte , gibt es den Namen des Displays davon zurück, anstatt den Namen des Thunderbolt-Displays .

Für die Auflösung meines Thunderbolt-Displays :

set theMainDisplayResolution to do shell script "system_profiler SPDisplaysDataType | grep -B 3 'Main Display:' | awk '/Resolution:/{print $2,$3,$4}'"
return theMainDisplayResolution

Result:
"2560 x 1440"

Wenn ich die Menüleiste auf das MacBook Pro umschalte , gibt es die Auflösung des Displays davon zurück, statt der Auflösung des Thunderbolt-Displays .


Sehen Sie sich auch meine Antworten auf Skript zum Verschieben der Menüleiste bei der Einrichtung von zwei Monitoren und Ändern der Anzeigeanordnung in OS X programmgesteuert für einige Dienstprogramme von Drittanbietern an, die Sie möglicherweise ebenfalls nützlich finden.

Hinweis: Ich habe keine Verbindung zu den Entwicklern der Dienstprogramme, die in den obigen Links erwähnt und in meinen Antworten verwendet werden.


Ein wenig über die Shell-Befehle verstehen , die in den do shell script Befehlen verwendet werden :

Befehlsteil des do shell script Befehls :

system_profiler SPDisplaysDataType | grep -B 5 'Main Display:' | awk '{sub(/^[ \t]+/, \"\"); print $0; exit}'
  • system_profiler- Meldet die Hardware- und Softwarekonfiguration des Systems.
    • SPDisplaysDataType – Generiert einen Textbericht, der nur etwa Grafiken und Anzeigen enthält.
  • |Pipeline zur direkten Ausgabe des vorangehenden Befehls zur Eingabe des nächsten Befehls .
  • grep- Dateimustersucher. Das Dienstprogramm grep durchsucht beliebige Eingabedateien und wählt Zeilen aus, die einem oder mehreren Mustern entsprechen.
    • −B num- Gibt vor jedem Treffer num Zeilen des führenden Kontextes aus.
    • 'Main Display:'Passendes Muster.
  • |Pipeline zur direkten Ausgabe des vorangehenden Befehls zur Eingabe des nächsten Befehls .
  • awk- Mustergesteuerte Scan- und Verarbeitungssprache.
    • sub(/^[ \t]+/, \"\")- Substitute String Function - sub(regexp, replacement)- Wird in diesem Fall verwendet, um führende Leerzeichen zu entfernen.
      • ^- Bestätigt die Position am Anfang der Zeichenfolge.
      • [ \t]- Übereinstimmung mit einem einzelnen Zeichen in der Liste.
        • space- Stimmt spacewörtlich mit dem Zeichen überein. Beachten Sie, dass spacehier ein einzelnes Leerzeichen (ASCII 32) bezeichnet wird.
        • \t- Entspricht einem Tabulatorzeichen (ASCII 9).
      • +- Übereinstimmungen zwischen einmal und unbegrenzt, so oft wie möglich, nach Bedarf zurückgeben (gierig).
      • \"\"- Ersatz ist mit nichts ( ""). Die ""sind mit Escapezeichen versehen \, sodass der Befehl kompiliert und an die Shell übergeben werden kann. Bei direkter Eingabe in der Befehlszeile ""müsste das nicht maskiert werden.
    • print $0- Druckt den vollständigen Datensatz. - In diesem Fall wird die fünfte Zeile darüber gedruckt Main Display:, ohne das führende Leerzeichen.
    • exit- Beendet nach dem Drucken des ersten Datensatzes .

Befehlsteil des do shell script Befehls :

system_profiler SPDisplaysDataType | grep -B 3 'Main Display:' | awk '/Resolution:/{print $2,$3,$4}'

In diesem do shell script Befehl macht der awk '/Resolution:/{print $2,$3,$4}'Teil Folgendes:

Die Ausgabe von zB:

$ system_profiler SPDisplaysDataType | grep -B 3 'Main Display:'
          Resolution: 2560 x 1440
          Pixel Depth: 32-Bit Color (ARGB8888)
          Display Serial Number: C08Z4120F6FB
          Main Display: Yes
$

Wird weitergeleitetawk und durchsucht die Eingabe nach einem Datensatz , Resolution:der die folgende Datensatzübereinstimmung findet :

          Resolution: 2560 x 1440

Der print $2,$3,$4 Befehl , druckt das zweite, dritte und vierte Feld des Datensatzes . Das ,Komma zwischen den $n Feldern ist ein Leerzeichen einzufügen . Die Ausgabe davon ist:

2560 x 1440
Steht das grep -B 3 für drei Zeilen davor und ist das ein awk-Substring? Würde plus eins für einen Breakout des grep awk und drucken würde es auch anderen helfen.
@DᴀʀᴛʜVᴀᴅᴇʀ, Ja, grep -B 3soll drei Zeilen vor dem Spiel einfügen und ich habe die Ersatzfunktion aus dem awkBefehl für die entfernt Resolution:, weil sie dort wirklich nicht benötigt wurde. Ich bin für ein paar Stunden unterwegs und werde etwas später eine Aufschlüsselung geben. Das heißt, ich persönlich würde wahrscheinlich cscreendie Informationen daraus verwenden und analysieren, system_profilerund ich werde auch ein Beispiel dafür hinzufügen, es sei denn, Sie sind gegen die Verwendung von Dienstprogrammen von Drittanbietern.
Ich persönlich würde es vorziehen, integriert zu verwenden, aber andere könnten es interessant finden, was Dritte tun können.
@DᴀʀᴛʜVᴀᴅᴇʀ, ich habe die Antwort aktualisiert, um ein wenig zu erklären, was die Shell-Befehle der do shell script Befehle tun.