¿Hay alguna manera de evitar que sus ventanas se muevan cuando se conecta un monitor externo?

9

Entonces, estoy usando Ubuntu 14.10 en mi computadora portátil y ocasionalmente lo conecto a mi televisor para una segunda pantalla. Mi televisor está a la izquierda de mi escritorio. Cuando lo habilito como monitor externo a la izquierda de la pantalla de mi computadora portátil, todas las ventanas que estaban en la pantalla de mi computadora portátil se mueven a la pantalla del televisor. Puedo moverlos hacia atrás, pero es realmente molesto tener que hacerlo siempre, especialmente cuando hay varias ventanas abiertas.

TV a la izquierda

Sin embargo, las ventanas no se mueven si configuro la pantalla de mi televisor a la derecha de la pantalla de mi computadora portátil (prácticamente). Pero esto es comprensiblemente confuso de usar, ya que es lo contrario de la configuración física. Además, no quiero mover mi escritorio.

TV a la derecha

Parece que Ubuntu o el servidor de visualización simplemente asume que el monitor más a la izquierda es el principal y donde deberían estar todas las ventanas. ¿Hay alguna manera de deshabilitar este comportamiento?

He estado revisando estos foros pero realmente no he visto a nadie publicar sobre esto. El hilo más cercano que encontré fue este, aunque no es exactamente el mismo problema.

Haga que Ubuntu NO mueva ventanas al apagar uno de los monitores múltiples

¿Alguien tiene alguna idea? Avísame si lo haces. ¡Gracias!

K0j0
fuente

Respuestas:

2

No encontré una configuración "secreta" para cambiar el comportamiento del comportamiento diseñado, como parece. En efecto, parece que se supone que la pantalla izquierda es la pantalla "base".

Sin embargo, es muy posible crear una solución alternativa, con esencialmente el mismo resultado. Puede crear una secuencia de comandos que, con ocasión de conectar una segunda pantalla, enumere todas las ventanas. Posteriormente, todas las ventanas que se mueven inicialmente a la pantalla izquierda, se desplazan de nuevo a la pantalla a la derecha, en un segundo o dos. Se conservará el tamaño de todas las ventanas.
Eso es lo que hace el siguiente script.

Dos versiones

Puede restaurar sus ventanas organizadas de dos maneras:

  • Ocasionalmente, con una tecla de acceso directo para ejecutar después de que la segunda pantalla esté conectada.
  • Automáticamente, ejecutando el script en segundo plano, esperando que se conecte su pantalla.

Cómo utilizar

preparativos

  • Instalar en pc wmctrl

    sudo apt-get install wmctrl

  • Busque los nombres de sus dos pantallas con la ayuda de xrandr, los nombres de las pantallas aparecerán justo antes de la palabra "conectado".

  • Copie Cualquiera de los siguientes scripts, en la sección de encabezado, reemplace en estas dos líneas los nombres de pantalla por los correctos:

    screen_1 = "LVDS1"     # your main screen (laptop)
    screen_2 = "VGA1"      # secundary screen (on the left)
    

    guardar el guión como move_windows.py

  • Asegúrese de que en la configuración de pantalla su pantalla secundaria esté a la izquierda. Las líneas superiores de las dos pantallas deben estar alineadas (como en la primera imagen de su pregunta).

Ejecute el script
: si usa el que se ejecuta ocasionalmente, ejecútelo después de que su segunda pantalla esté conectada.

    python3 /path/to/move_windows.py

Es posible que desee agregarlo a un método abreviado de teclado si cree que hace lo que debería hacer. Elija: Configuración del sistema> "Teclado"> "Métodos abreviados"> "Métodos abreviados personalizados". Haga clic en "+" y agregue el comando:

  • Si usa el que se ejecuta en segundo plano, también ejecútelo con el comando:

    python3 /path/to/move_windows.py
    

    Si funciona como se esperaba, agréguelo a sus aplicaciones de inicio: Tablero> Aplicaciones de inicio> Agregar

Probé el script con mi computadora portátil (a la derecha) y dos pantallas diferentes (a la izquierda). El resultado fue el mismo.

pantalla de portátil

ingrese la descripción de la imagen aquí

conectando sin script

ingrese la descripción de la imagen aquí

conectando con el script en ejecución

ingrese la descripción de la imagen aquí

Después de que el script hizo su trabajo, las ventanas se "dejarán solas" (por supuesto), y puede organizar sus ventanas a su manera.

El guion (es)

1. Versión "manual", para ejecutar después de conectar la pantalla

#!/usr/bin/env python3
import subprocess
import time

#--
screen_2 = "LVDS1"       # replace with your internal screen (right)
screen_2 = "VGA1"        # replace with your external screen (left)
#--

def get(cmd):
    return subprocess.check_output(["/bin/bash", "-c",  cmd]).decode("utf-8")

def get_shift(xr_output):
    lines = [l for l in xr_output.splitlines() if " connected" in l][0].split()
    return int([it for it in lines if "x" in it][0].split("x")[0])

def shift_windows(shift):
    w_data = [l.split() for l in get("wmctrl -lG").splitlines()]
    relevant = []
    for w in w_data:
        props = get("xprop -id "+w[0])
        if (int(w[2]) < shift, "_TYPE_NORMAL" in props, "TYPE_DIALOG" in props).count(True) == 2:
            command = "wmctrl -ir "+w[0]+" -e 0,"+(",").join([str(int(w[2])+shift), w[3], w[4], w[5]])
            subprocess.Popen(["/bin/bash", "-c", command])

shift_windows(get_shift(get("xrandr")))

2. Versión automática, para ejecutar en segundo plano.

#!/usr/bin/env python3
import subprocess
import time

#--
screen_2 = "LVDS1"       # replace with your internal screen (right)
screen_2 = "VGA1"        # replace with your external screen (left)
#--

def get(cmd):
    return subprocess.check_output(["/bin/bash", "-c",  cmd]).decode("utf-8")

def get_shift(xr_output):
    lines = [l for l in xr_output.splitlines() if " connected" in l][0].split()
    return int([it for it in lines if "x" in it][0].split("x")[0])

def shift_windows(shift):
    w_data = [l.split() for l in get("wmctrl -lG").splitlines()]
    relevant = []
    for w in w_data:
        props = get("xprop -id "+w[0])
        if (int(w[2]) < shift, "_TYPE_NORMAL" in props, "TYPE_DIALOG" in props).count(True) == 2:
            command = "wmctrl -ir "+w[0]+" -e 0,"+(",").join([str(int(w[2])+shift), w[3], w[4], w[5]])
            subprocess.Popen(["/bin/bash", "-c", command])

while True:
    try:
        screen_info1 = get("xrandr")
        time.sleep(5)
        screen_info2 = get("xrandr")
        check = screen_2+" connected"
        if (check in screen_info1, check in screen_info2) == (False, True):
            time.sleep(5)
            shift_windows(get_shift(screen_info2))
    except:
        pass
Jacob Vlijm
fuente
Habilidades gravemente enfermas, Jacob!
don.joey
@ K0j0 ¿Lo lograste?
Jacob Vlijm
@JacobVlijm No estoy seguro de si sondear cada 5 segundos es la mejor solución (¿no hay posibilidad de eventos?). De todos modos, si está interesado en convertir este script en un indicador de Unidad ( como estos aquí ), póngase en contacto.
Peterino
@Peterino Si existe una señal controlada por eventos, sería mi primera opción. Al mismo tiempo: si un script de fondo está bien escrito, su carga adicional debería (y puede) ser prácticamente nula, y siempre pruebo mis scripts específicamente en eso. Yo mismo ejecuto un número cambiante de scripts de fondo. Incluso todos juntos no tienen ningún efecto notable. Recuerde que numerosos bucles se ejecutan por definición en su sistema. Acerca de la sugerencia del indicador de Unidad: definitivamente estoy interesado en aprender cómo crear un indicador, ya sea para esta u otra situación :).
Jacob Vlijm
@JacobVlijm Parece que la colocación automática de ventanas ocurrirá automáticamente a partir de una de las próximas versiones de Ubuntu ("trabajo en progreso"), según una fuente de Canonical . Probablemente no valga la pena invertir en los últimos meses en el lanzamiento actual. Sin embargo, volveré a verificar con los desarrolladores de Mir en IRC # ubuntu-mir @ freenode.
Peterino