Czy istnieje sposób, aby zapobiec przesuwaniu się okien po podłączeniu zewnętrznego monitora?

9

Tak więc używam Ubuntu 14.10 na swoim laptopie i od czasu do czasu podłączam go do telewizora na drugi ekran. Mój telewizor znajduje się po lewej stronie biurka. Po włączeniu go jako zewnętrznego monitora po lewej stronie ekranu laptopa wszystkie okna, które były na ekranie laptopa, przechodzą na ekran telewizora. Mogę je cofnąć, ale to naprawdę denerwujące, że muszę to robić za każdym razem, zwłaszcza gdy jest otwartych kilka okien.

TV po lewej

Okna się jednak nie poruszają, jeśli ustawię ekran telewizora po prawej stronie ekranu laptopa (praktycznie). Ale jest to zrozumiałe mylące w użyciu, ponieważ jest przeciwieństwem konfiguracji fizycznej. Nie chcę też przenosić biurka.

TV po prawej

Wygląda na to, że Ubuntu lub serwer wyświetlania po prostu zakłada, że ​​najbardziej wysunięty w lewo monitor jest głównym i tam, gdzie powinny znajdować się wszystkie okna. Czy istnieje sposób na wyłączenie tego zachowania?

Sprawdzałem te fora, ale tak naprawdę nie widziałem nikogo na ten temat. Najbliższym wątkiem, który znalazłem, był ten, choć nie jest to ten sam problem.

Spraw, aby Ubuntu NIE przenosił okien podczas wyłączania jednego z wielu monitorów

Czy ktoś ma jakieś pomysły? Daj mi znać, jeśli tak. Dzięki!

K0j0
źródło

Odpowiedzi:

2

Nie znalazłem „tajnego” ustawienia, które zmieniłoby zachowanie, jak się wydaje, zaprojektowanego zachowania. Wygląda to tak, jakby zakładano, że lewy ekran jest ekranem „podstawowym”.

Jednak bardzo możliwe jest stworzenie obejścia, z zasadniczo takim samym rezultatem. Możesz utworzyć skrypt, który przy okazji podłączania drugiego ekranu wyświetla wszystkie okna. Następnie wszystkie okna, które są początkowo przenoszone na lewy ekran, są przenoszone z powrotem na ekran po prawej stronie, w ciągu sekundy lub dwóch. Rozmiar wszystkich okien zostanie zachowany.
Tak właśnie działa poniższy skrypt.

Dwie wersje

Możesz przywrócić ustawione okna na dwa sposoby:

  • Czasami klawisz skrótu uruchamiany po podłączeniu drugiego ekranu.
  • Automatycznie uruchamiając skrypt w tle, czekając na podłączenie ekranu.

Jak używać

przygotowania

  • zainstalować wmctrl

    sudo apt-get install wmctrl

  • Wyszukaj nazwy swoich dwóch ekranów za pomocą xrandr, nazwy ekranów będą znajdować się tuż przed słowem „połączony”.

  • Skopiuj Jeden z poniższych skryptów, w sekcji nagłówka, zamień w tych dwóch wierszach nazwy ekranowe na poprawne:

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

    zapisz skrypt jako move_windows.py

  • Upewnij się, że w ustawieniach ekranu drugi ekran jest po lewej stronie. Górne linie dwóch ekranów muszą być w jednej linii (jak na pierwszym obrazku twojego pytania).

Uruchom skrypt
- jeśli używasz tego do uruchamiania od czasu do czasu, uruchom go po podłączeniu drugiego ekranu.

    python3 /path/to/move_windows.py

Możesz dodać go do skrótu klawiaturowego, jeśli uważasz, że robi to, co powinien, wybierz: Ustawienia systemu> „Klawiatura”> „Skróty”> „Skróty niestandardowe”. Kliknij „+” i dodaj polecenie:

  • Jeśli używasz tego do uruchamiania w tle, uruchom go również za pomocą polecenia:

    python3 /path/to/move_windows.py
    

    Jeśli działa tak, jak chciałeś, dodaj go do aplikacji startowych: Dash> Aplikacje startowe> Dodaj

Testowałem skrypt z moim laptopem (po prawej) i dwoma różnymi ekranami (po lewej). Wynik był taki sam.

ekran laptopa

wprowadź opis zdjęcia tutaj

łączenie bez skryptu

wprowadź opis zdjęcia tutaj

łączenie się z działającym skryptem

wprowadź opis zdjęcia tutaj

Gdy skrypt wykona swoją pracę, okna będą „pozostawione same” (oczywiście), a ty możesz ustawić swoje okna na swój sposób.

Skrypty

1. Wersja „Ręczna”, uruchamiana po podłączeniu ekranu

#!/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. Wersja automatyczna do działania w tle

#!/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
źródło
Poważnie chore umiejętności, Jacob!
don.joey
@ K0j0 Udało ci się?
Jacob Vlijm
@JacobVlijm Nie jestem pewien, czy odpytywanie co 5 sekund jest najlepszym rozwiązaniem (czy nie ma możliwości wywołania zdarzenia?). W każdym razie, jeśli chcesz zmienić ten skrypt w wskaźnik Jedności ( jak te tutaj ), skontaktuj się z nami.
Peterino,
@Peterino Jeśli istnieje sygnał sterowany zdarzeniem, byłby to mój pierwszy wybór. Jednocześnie: jeśli skrypt w tle jest dobrze napisany, jego dodatkowe obciążenie powinno (i może) być praktycznie żadne, a ja zawsze testuję swoje skrypty właśnie na tym. Sam uruchamiam zmieniającą się liczbę skryptów w tle. Nawet wszystkie razem nie mają zauważalnego wpływu. Pamiętaj, że wiele pętli z definicji działa w twoim systemie. O sugestii wskaźnika Unity: Jestem zdecydowanie zainteresowany nauczeniem się, jak stworzyć wskaźnik dla tej lub innej sytuacji :).
Jacob Vlijm
@JacobVlijm Wygląda na to, że automatyczne umieszczanie okien nastąpi automatycznie, począwszy od jednej z kolejnych wersji Ubuntu („praca w toku”), zgodnie ze źródłem w Canonical . Prawdopodobnie nie warto inwestować przez pozostałe kilka miesięcy w obecną wersję. Jednak sprawdzę dwukrotnie z programistami Mir na IRC # ubuntu-mir @ freenode.
Peterino,