Есть ли способ предотвратить перемещение ваших окон при подключении внешнего монитора?

9

Итак, я использую Ubuntu 14.10 на своем ноутбуке и иногда подключаю его к телевизору для второго экрана. Мой телевизор находится слева от моего стола. Когда я включаю его в качестве внешнего монитора слева от экрана моего ноутбука, все окна, которые были на экране моего ноутбука, переходят на экран телевизора. Я могу переместить их назад, но это действительно раздражает, когда приходится делать это каждый раз, особенно когда открыто несколько окон.

ТВ слева

Однако окна не двигаются, если я установил экран телевизора справа от экрана моего ноутбука (виртуально). Но это по понятным причинам сбивает с толку, поскольку это противоположно физическим настройкам. Кроме того, я не хочу двигать свой стол.

Телевизор справа

Похоже, что Ubuntu или сервер дисплея просто предполагают, что самый левый монитор является основным и где должны быть все окна. Есть ли способ отключить это поведение?

Я проверял эти форумы, но на самом деле не видел ни одного сообщения об этом. Самый близкий поток, который я нашел, был этим, хотя это не совсем та же самая проблема.

Получить Ubuntu, чтобы НЕ перемещать окна при отключении одного из нескольких мониторов

У кого-нибудь есть идеи? Пожалуйста, дайте мне знать, если вы делаете. Спасибо!

K0j0
источник

Ответы:

2

Я не нашел «секретной» настройки, которая бы изменяла поведение, как кажется, разработанного поведения. Это действительно выглядит так, как будто левый экран считается «базовым» экраном.

Однако вполне возможно создать обходной путь, по сути, с тем же результатом. Вы можете создать скрипт, который при подключении второго экрана выводит список всех окон. Впоследствии все окна, которые изначально перемещены на левый экран, смещаются назад на экран справа, в течение секунды или двух. Размер всех окон будет сохранен.
Вот что делает скрипт ниже.

Две версии

Вы можете восстановить расположенные окна двумя способами:

  • Иногда с помощью сочетания клавиш запускается после подключения второго экрана.
  • Автоматически запускает скрипт в фоновом режиме, ожидая подключения вашего экрана.

Как пользоваться

препараты

  • устанавливать wmctrl

    sudo apt-get установить wmctrl

  • Посмотрите названия ваших двух экранов с помощью xrandr, названия экранов будут непосредственно перед словом «подключен».

  • Скопируйте Либо один из приведенных ниже сценариев, в разделе заголовка, замените в этих двух строках имена экрана правильными:

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

    сохранить скрипт как move_windows.py

  • Убедитесь, что в настройках дисплея ваш дополнительный экран находится слева. Верхние строки двух экранов должны быть в одной строке (как на первом изображении вашего вопроса).

Запустите скрипт
- если вы используете тот, который запускается время от времени, запустите его после подключения второго экрана.

    python3 /path/to/move_windows.py

Возможно, вы захотите добавить его к сочетанию клавиш, если считаете, что он делает то, что должен делать. Выберите: «Системные настройки»> «Клавиатура»> «Сочетания клавиш»> «Пользовательские сочетания клавиш». Нажмите «+» и добавьте команду:

  • Если вы используете тот, который запускается в фоновом режиме, также запустите его командой:

    python3 /path/to/move_windows.py
    

    Если он работает так, как вы хотели, добавьте его в свои запускаемые приложения: Dash> Startup Applications> Add

Я протестировал скрипт на своем ноутбуке (справа) и двух разных экранах (слева). Результат был таким же.

экран ноутбука

введите описание изображения здесь

подключение без скрипта

введите описание изображения здесь

соединение с запущенным скриптом

введите описание изображения здесь

После того, как скрипт выполнит свою работу, окна будут «оставлены в покое» (конечно), и вы можете расположить свои окна по-своему.

Сценарий (ы)

1. «Ручная» версия, для запуска после подключения экрана

#!/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. Автоматическая версия, для запуска в фоновом режиме

#!/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
Якоб Влейм
источник
Серьезно больные навыки, Джейкоб!
don.joey
@ K0j0 Ты справился?
Джейкоб Влийм
@JacobVlijm Не уверен, что опрос каждые 5 секунд - лучшее решение (нет ли возможности, управляемой событиями?). В любом случае, если вы заинтересованы в том, чтобы превратить этот скрипт в индикатор Unity ( как здесь ), пожалуйста, свяжитесь с нами.
Петерино
@Peterino Если существует управляемый событиями сигнал, это будет мой первый выбор. В то же время: если фоновый скрипт хорошо написан, его дополнительное бремя должно (и может быть) практически отсутствовать, и я всегда тестирую свои сценарии специально на этом. Я сам запускаю изменяющееся количество фоновых скриптов. Даже все вместе не имеют заметного эффекта вообще. Помните, что в вашей системе по определению работает множество циклов. О предложении индикатора Unity: мне определенно интересно узнать, как создать индикатор, для этой или другой ситуации :).
Джейкоб Влейм
@JacobVlijm По словам источника в Canonical, автоматическое размещение окон будет происходить автоматически, начиная с одного из следующих выпусков Ubuntu («работа в процессе») . Вероятно, не стоит вкладывать деньги в оставшиеся несколько месяцев текущего выпуска. Я еще раз проверю разработчиков Mir на IRC # ubuntu-mir @ freenode.
Петерино