3 votos

¿Cómo se puede saber qué monitor tiene la barra de menús en AppleScript?

Jugando con AppleScript quiero manipular la ubicación de unos Windows con position pero tengo un problema para definir el monitor. Actualmente tengo varios monitores de diferentes tamaños y marcas a los que me conecto con mi MacBook durante mis viajes. Lo único que se repite en los cuatro monitores a los que me conecto es que el monitor que quiero manipular incluye la barra de menú.

Al realizar las pruebas con do shell script "system_profiler SPDisplaysDataType No estoy seguro de si el texto devuelto de Main Display: Yes considera que el principal es donde reside la barra de menú de la extracción:

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

Si mi suposición de la Main Display es correcto ¿cómo debo grepar adecuadamente la resolución de la pantalla principal identificada para poder manipular el Windows?

Cuando investigo parecería que algunos comúnmente sólo pisan cada pantalla:

Así que no sé si esto sería dos preguntas en una. Estoy algo confundido sobre cómo se determina la secuencia cuando se conecta a múltiples monitores (como hoy podría estar conectado a una pantalla thunderbolt pero mañana podría estar conectado a dos monitores Dells a través de mis dos DisplayPorts) y si hay una manera de apuntar a un monitor en particular basado en la barra de menú.

Ya puedo detectar la aplicación y su tamaño con:

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

pero mi problema es determinar la resolución para poder calcular la position y bounds para mover la ventana de la aplicación.

3voto

wch1zpink Puntos 11

Sólo he podido probarlo utilizando la pantalla principal de mi MacBook Pro, y con Airplay activado Utilizando mi televisor como segundo monitor (a través de todo el asunto de Airplay y Apple TV)

En mis Preferencias de Pantalla en Preferencias del Sistema, si tenía la barra de menús activa en mi MBP, cuando ejecutaba este script era capaz de obtener el nombre de la pantalla activa y sus límites.

Cuando la pantalla activa era mi MBP, mis resultados eran:

enter image description here


En mis Preferencias de Pantalla en las Preferencias del Sistema, si tenía la barra de menú activa en mi TV a través de airplay, cuando ejecutaba este script era capaz de obtener el nombre de la pantalla activa y sus límites también

Estoy seguro de que si estuviera "cableado" a otras pantallas, no obtendría un resultado de "valor perdido" para el nombre de la pantalla del escritorio actual en el script


enter image description here


tell application "System Events"
    set currentDesktop to display name of current desktop
    tell application "Finder"
        set currentDesktopBounds to bounds of window of desktop
    end tell
end tell

Esta versión tiene como objetivo la ventana más frontal de la pantalla activa, para establecer sus límites

property theBoundz : {}

tell application "System Events"
    set currentDesktop to display name of current desktop
    tell application "Finder"
        set currentDesktopBounds to bounds of window of desktop
        copy currentDesktopBounds to theBoundz
        set thePosition to (items 1 thru 2) of theBoundz
        set theSize to (items 3 thru 4) of theBoundz
    end tell
    delay 5 -- gives you time to bring the application window you want to target to the front
    tell window 1 of (process 1 whose it is frontmost) to set {position, size} to {thePosition, theSize}
end tell

Tomando los resultados de la segunda imagen {0, 0, 3600, 1080}, suponiendo que tengo ambos monitores en la pestaña de arreglos de las preferencias de visualización, configurados lado a lado y la barra de menú está activa en el monitor de la derecha, y quiero mover la ventana que estoy viendo actualmente a mi segundo monitor. Establecería los límites a {-1680, 0, 3600, 1080} que teóricamente debería mover mi ventana actual a la otra pantalla. Digo teóricamente porque no lo he probado a fondo. Ese número negativo es el valor del ancho de los límites del otro monitor (mostrado en la primera imagen)

0 votos

¿Puedes aclarar cómo se supone que funciona esto para múltiples monitores? En mi configuración de dos monitores el resultado de bounds of window of desktop es siempre el rectángulo total que incluye ambas pantallas, por lo que un 1920 x 1080 junto a un 1280 x 800 da 3200 x 1080 siempre.

0 votos

En la siguiente imagen, verá que la barra de menú, que está marcada con un círculo rojo, puede moverse hacia adelante y hacia atrás entre las pantallas conectadas en Preferencias del Sistema/Displays, cuando la opción de "Reflejar pantallas" está deseleccionada. Cualquiera que sea la pantalla que contenga la barra de menú, estará en las dimensiones de la pantalla que devuelve el código AppleScript. i.imgur.com/vPD5upS.jpg

2voto

user3439894 Puntos 5883

Probado en mi MacBook Pro con un Pantalla Thunderbolt adjunta y la Barra de menús en él, funcionó lo siguiente:

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

Si cambio el Barra de menús a la MacBook Pro , devuelve el nombre de la Mostrar de la misma, en lugar de la nombre de la Pantalla Thunderbolt .

Para el Resolución de mi Pantalla Thunderbolt :

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"

Si cambio el Barra de menús a la MacBook Pro , devuelve el resolución de la Mostrar de la misma, en lugar de la resolución de la Pantalla Thunderbolt .


Además, echa un vistazo a mis respuestas a, script para reubicar la barra de menús en una configuración de dos monitores y Cambiar la disposición de la pantalla en OS X mediante programación para un par de utilidades de terceros que también puede encontrar útiles.

Nota: No tengo ninguna afiliación con los desarrolladores de las utilidades mencionadas y utilizadas en mis respuestas en los enlaces anteriores.


Entender un poco sobre el comandos del shell utilizado en el do shell script comandos :

La parte del comando del do shell script comando :

system_profiler SPDisplaysDataType | grep -B 5 'Main Display:' | awk '{sub(/^[ \t]+/, \"\"); print $0; exit}'
  • system_profiler - Informa de la configuración del hardware y el software del sistema.
    • SPDisplaysDataType - Genera un informe de texto que contiene sólo sobre Gráficos y Pantallas.
  • | Tubo para dirigir salida del procedimiento comando a entrada del siguiente comando .
  • grep - Buscador de patrones de archivos. La página web grep busca en cualquier archivo de entrada, seleccionando las líneas que coinciden con uno o más patrones.
    • −B num - Imprimir num líneas de contexto principal antes de cada partido.
    • 'Main Display:' Patrón de coincidencia.
  • | Tubo para dirigir salida del procedimiento comando a entrada del siguiente comando .
  • awk - Exploración y procesamiento del lenguaje dirigido por patrones.
    • sub(/^[ \t]+/, \"\") - Función de sustitución de cadenas - sub(regexp, replacement) - Se utiliza en este caso para eliminar los espacios en blanco iniciales.
      • ^ - Afirma la posición al principio de la cadena.
      • [ \t] - Coincidir con un solo carácter presente en la lista.
        • space - Coincide con el space carácter, literalmente. Tenga en cuenta que space se utiliza aquí para denotar un solo carácter de espacio (ASCII 32).
        • \t - Coincide con un carácter de tabulación (ASCII 9).
      • + - Empareja entre una y un número ilimitado de veces, tantas como sea posible, devolviendo lo necesario (codicioso).
      • \"\" - La sustitución es con nada ( "" ). El "" se escapan, \ para que el comando pueda ser compilado y pasado al shell. Si se introduce directamente en la línea de comandos, el "" no necesitaría escaparse.
    • print $0 - Imprime el registro completo. - En este caso, imprime la quinta línea de arriba Main Display: san el espacio en blanco inicial.
    • exit - Sale después de imprimir la primera registro .

La parte del comando del do shell script comando :

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

En este do shell script comando el awk '/Resolution:/{print $2,$3,$4}' hace lo siguiente:

El salida de por ejemplo:

$ 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
$

Obtiene canalizado a awk y busca el entrada para un registro que contiene Resolution: que encuentra lo siguiente registro partido:

          Resolution: 2560 x 1440

El print $2,$3,$4 comando , imprime el segundo, el tercero y el cuarto campos de la registro . El , coma entre el $n campos es insertar un espacio . El salida del cual es:

2560 x 1440

0 votos

¿Es el grep -B 3 para tres líneas antes y es la subcadena awk? Sería más uno para una ruptura del grep awk e imprimirlo ayudaría a otros, también.

0 votos

@DV, Sí, grep -B 3 es incluir tres líneas antes del coincide con y he quitado el función de sustitución de la awk para el Resolution: porque realmente no era necesario allí. Voy a salir por unas horas y daré un resumen un poco más tarde. Dicho esto, yo personalmente probablemente usaría cscreen y parsear la información de la misma sobre system_profiler y añadiré un ejemplo de ello también, a menos que estés en contra de usar utilidades de terceros.

0 votos

Personalmente, prefiero utilizar el sistema integrado, pero a otros les puede resultar interesante lo que pueden hacer los terceros.

2voto

En mis pruebas, tienes razón en que la pantalla principal es la que tiene el menú asignado en Displays System Prefs. He probado moviendo la barra de menú de una pantalla a otra y ejecutando tu script. Los resultados sugieren que dondequiera que esté la barra de menú, esa pantalla tendrá "Pantalla principal: Sí" en su información.

Para analizar la resolución, utilizaría el argumento -xml del comando system_profiler para obtener un texto coherente que buscar, y luego utilizaría los delimitadores de elementos de texto de Apple para analizar los datos. Escribí este script, y cuando cambio el menú de un lado a otro, devuelve la resolución de la pantalla principal actual. Puede que tengas que ajustar los delimitadores dependiendo de lo que tu sistema operativo devuelva para el informe del perfil del sistema.

He añadido comentarios en línea en el código de abajo para explicar lo que el script está haciendo.

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

EDIT: Debido a que publicaste la forma regular del system_profiler arriba, reescribí el script para analizar esa salida. Parece un poco más arriesgado para mí que el uso de la xml, pero debe compilar y ejecutar correctamente en su sistema sin ningún ajuste.

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

0 votos

Si copio y pego tu código en el editor script, aunque compila, sin embargo, da error. ¿Se supone que debo cambiar algo en el código que has publicado para que funcione, si es así qué?

0 votos

Probablemente necesitarás comprobar el informe xml que devuelve para asegurarte de que las cosas que he puesto como delimitadores de elementos de texto son las mismas en tu sistema. Puedes añadir una línea de código "return pfl" justo después de la primera línea de código para ver qué devuelve tu sistema. Si, por ejemplo, "</data><key>_name</key>" no existe (ignorando los espacios en blanco) en tu informe, tendrías que cambiarlo por lo que viene justo antes del nombre de la pantalla. Si "<key>_spdisplays_resolution</key><string>" no existe, cámbialo en consecuencia. Estoy corriendo Sierra 10.12.6, es posible que tengas una versión diferente con un informe diferente.

0 votos

Si quieres postear aquí el xml (qué pfl hay en ese script), buscaré los delimitadores y revisaré el script para reflejarlo.

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