Existe-t-il un moyen d'empêcher vos fenêtres de bouger lorsqu'un moniteur externe est connecté?

9

Donc, j'utilise Ubuntu 14.10 sur mon ordinateur portable et le branche parfois sur mon téléviseur pour un deuxième écran. Mon téléviseur est à gauche de mon bureau. Lorsque je l'active en tant que moniteur externe à gauche de l'écran de mon ordinateur portable, toutes les fenêtres qui se trouvaient sur l'écran de mon ordinateur portable se déplacent vers l'écran du téléviseur. Je peux les reculer, mais c'est vraiment ennuyeux de devoir le faire à chaque fois, surtout quand plusieurs fenêtres sont ouvertes.

TV à gauche

Cependant, les fenêtres ne bougent pas si je règle (virtuellement) l'écran de mon téléviseur à droite de l'écran de mon ordinateur portable. Mais c'est naturellement déroutant à utiliser car c'est l'opposé de la configuration physique. De plus, je ne veux pas déplacer mon bureau.

TV à droite

Il semble qu'Ubuntu ou le serveur d'affichage suppose simplement que le moniteur le plus à gauche est le principal et où toutes les fenêtres devraient être. Existe-t-il un moyen de désactiver ce comportement?

J'ai consulté ces forums, mais je n'ai vraiment vu personne publier à ce sujet. Le fil le plus proche que j'ai trouvé était celui-ci, bien que ce ne soit pas tout à fait le même problème.

Demandez à Ubuntu de NE PAS déplacer les fenêtres lorsque vous éteignez l'un des plusieurs moniteurs

Quelqu'un a des idées? Veuillez me le faire savoir si vous le faites. Merci!

K0j0
la source

Réponses:

2

Je n'ai pas trouvé de paramètre "secret" pour changer le comportement du comportement, semble-t-il, conçu. Il semble en effet que l'écran de gauche soit supposé être l'écran "de base".

Il est cependant très bien possible de créer une solution de contournement, avec essentiellement le même résultat. Vous pouvez créer un script qui, à l'occasion de la connexion d'un deuxième écran, répertorie toutes les fenêtres. Par la suite, toutes les fenêtres qui sont déplacées initialement vers l'écran de gauche, sont décalées vers l'écran de droite, en une ou deux secondes. La taille de toutes les fenêtres sera conservée.
C'est ce que fait le script ci-dessous.

Deux versions

Vous pouvez restaurer vos fenêtres organisées de deux manières:

  • Parfois, avec une touche de raccourci à exécuter après la connexion du deuxième écran.
  • Automatiquement, en exécutant le script en arrière-plan, en attendant que votre écran soit connecté.

Comment utiliser

les préparatifs

  • Installer wmctrl

    sudo apt-get install wmctrl

  • Recherchez les noms de vos deux écrans à l'aide de xrandr, les noms des écrans seront juste avant le mot "connecté".

  • Copiez Soit l'un des scripts ci-dessous, dans la section head, remplacez dans ces deux lignes les noms d'écran par les bons:

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

    enregistrer le script sous move_windows.py

  • Assurez-vous que dans les paramètres d'affichage, votre écran secondaire est à gauche. Les lignes supérieures des deux écrans doivent être alignées (comme dans la première image de votre question).

Exécutez le script
- Si vous utilisez celui pour exécuter occasionnellement, exécutez-le après que votre deuxième écran est connecté.

    python3 /path/to/move_windows.py

Vous pouvez l'ajouter à un raccourci clavier si vous pensez qu'il fait ce qu'il doit faire, choisissez: Paramètres système> "Clavier"> "Raccourcis"> "Raccourcis personnalisés". Cliquez sur le "+" et ajoutez la commande:

  • Si vous utilisez celui à exécuter en arrière-plan, exécutez-le également par la commande:

    python3 /path/to/move_windows.py
    

    S'il agit comme vous le souhaitiez, ajoutez-le à vos applications de démarrage: Dash> Startup Applications> Add

J'ai testé le script avec mon ordinateur portable (à droite) et deux écrans différents (à gauche). Le résultat était le même.

écran d'ordinateur portable

entrez la description de l'image ici

connexion sans script

entrez la description de l'image ici

connexion avec le script en cours d'exécution

entrez la description de l'image ici

Une fois que le script aura fait son travail, les fenêtres seront "laissées seules" (bien sûr), et vous pourrez organiser vos fenêtres à votre façon.

Le (s) script (s)

1. Version "manuelle", à exécuter après la connexion de l'écran

#!/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. Version automatique, à exécuter en arrière-plan

#!/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
la source
Des compétences sérieusement malades, Jacob!
don.joey
@ K0j0 Avez-vous réussi?
Jacob Vlijm
@JacobVlijm Je ne sais pas si l'interrogation toutes les 5 secondes est la meilleure solution (n'y a-t-il pas une possibilité événementielle?). Quoi qu'il en soit, si vous souhaitez transformer ce script en indicateur Unity ( comme ceux-ci ici ), veuillez nous contacter.
Peterino
@Peterino S'il existe un signal événementiel, ce serait mon premier choix. Dans le même temps: si un script d'arrière-plan est bien écrit, sa charge supplémentaire devrait (et peut) être pratiquement nulle, et je teste toujours mes scripts spécifiquement sur cela. Je lance moi-même un nombre changeant de scripts d'arrière-plan. Même tous ensemble, ils n'ont aucun effet notable. N'oubliez pas que de nombreuses boucles sont exécutées par définition sur votre système. À propos de la suggestion d'indicateur Unity: Je suis vraiment intéressé à apprendre à créer un indicateur, pour cette situation ou une autre :).
Jacob Vlijm
@JacobVlijm On dirait que le placement automatique des fenêtres se fera automatiquement à partir de l'une des prochaines versions d'Ubuntu ("work in progress"), selon une source de Canonical . Cela ne vaut probablement pas la peine d'investir dans les quelques mois restants sur la version actuelle. Je revérifierai cependant avec les développeurs Mir sur IRC # ubuntu-mir @ freenode.
Peterino