Перемещение окон между экранами в режиме двойного экрана

У меня есть ноутбук и 27-дюймовый монитор. У меня Qt работает на одном мониторе, а Pycharm - на другом. Есть ли способ сделать комбинацию клавиш, чтобы поменять местами все окна между обоими экранами. Причина в том, что я хочу программировать только на большом экране. У меня уже есть 4 рабочих пространства, и все они уже используются.

Вывод xrandr:

Screen 0: minimum 320 x 200, current 3840 x 1080, maximum 32767 x 32767
eDP1 connected 1920x1080+1920+0 (normal left inverted right x axis y axis) 344mm x 193mm
   1920x1080      60.2*+   59.9  
   1680x1050      60.0     59.9  
   1600x1024      60.2  
   1400x1050      60.0  
   1280x1024      60.0  
   1440x900       59.9  
   1280x960       60.0  
   1360x768       59.8     60.0  
   1152x864       60.0  
   1024x768       60.0  
   800x600        60.3     56.2  
   640x480        59.9  
HDMI1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 597mm x 336mm
   1920x1080      60.0*+   50.0     59.9  
   1920x1080i     60.1     50.0     60.0  
   1600x1200      60.0  
   1680x1050      59.9  
   1280x1024      75.0     60.0  
   1440x900       59.9  
   1280x960       60.0  
   1366x768       59.8  
   1152x864       75.0  
   1280x720       60.0     50.0     59.9  
   1024x768       75.1     70.1     60.0  
   832x624        74.6  
   800x600        72.2     75.0     60.3     56.2  
   720x576        50.0  
   720x480        60.0     59.9  
   640x480        75.0     72.8     66.7     60.0     59.9  
   720x400        70.1  
DP1 disconnected (normal left inverted right x axis y axis)
HDMI2 disconnected (normal left inverted right x axis y axis)
VIRTUAL1 disconnected (normal left inverted right x axis y axis)

1 ответ

Решение

1. Скрипт, чтобы поменять местами все окна с экрана 1 -> с экрана 2 и наоборот

Сценарий предполагает, что экраны имеют одинаковое вертикальное разрешение, а левый экран является основным. Горизонтальное разрешение обоих экранов ищется скриптом.

Как настроить

Скрипт нужен wmctrl быть установленным:

sudo apt-get install wmctrl
  1. Скопируйте приведенный ниже скрипт в пустой файл и сохраните его как swap_windows (без расширения) в ~/.bin, Создайте каталог, если он еще не существует, и сделайте скрипт исполняемым.
  2. Если вы только что создали каталог ~/bin (его еще не было), либо выйдите из системы, либо войдите в терминал: source ~/.profile,
  3. Тестовый запуск скрипта с помощью команды:

    swap_windows
    
  4. Если все работает как положено, добавьте ярлык; выберите: Системные настройки> "Клавиатура" > "Ярлыки" > "Пользовательские ярлыки". Нажмите "+" и добавьте команду

Сценарий

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

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

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

def get_shiftleft(xr_output):
    lines = [l for l in xr_output.splitlines() if  "+0" in l and not "+0+0" in l][0].split()
    return -int([it for it in lines if "x" in it][0].split("x")[0])

def swap_windows():
    xr_output = get("xrandr")
    shift_r = get_shiftright(xr_output)
    shift_l = get_shiftleft(xr_output)
    w_data = [l.split() for l in get("wmctrl -lG").splitlines()]
    for w in w_data:
        props = get("xprop -id "+w[0])
        if any(["_TYPE_NORMAL" in props, "TYPE_DIALOG" in props]):    
            if 0 < int(w[2]) < shift_r:
                shift = shift_r
            elif shift_r-shift_l > int(w[2]) >= shift_r:
                shift = -shift_r
            else:
                shift = 0
            command = "wmctrl -ir "+w[0]+" -e 0,"+(",").join([str(int(w[2])+shift), str(int(w[3])-28), w[4], w[5]])
            subprocess.Popen(["/bin/bash", "-c", command])     
swap_windows()



2. Скрипт для перемещения (всех) окон с одного монитора на другой

Сценарий ниже перемещает окна в настройке двух мониторов с одного экрана на другой:

  • с левого на правый монитор ->

    или же

  • с правого на левый монитор <-

В зависимости от аргумента вы используете его (left или же right)

Сценарий (опять же) предполагает, что экраны имеют одинаковое вертикальное разрешение, а левый экран является основным. Горизонтальное разрешение обоих экранов ищется скриптом.

Как настроить

Скрипт нужен wmctrl быть установленным:

sudo apt-get install wmctrl
  1. Скопируйте приведенный ниже скрипт в пустой файл и сохраните его как shift_windows (без расширения) в ~/.bin, Создайте каталог, если он еще не существует, и сделайте скрипт исполняемым.
  2. Если вы только что создали каталог ~/bin (его еще не было), либо выйдите из системы, либо войдите в терминал: source ~/.profile,
  3. тестовый запуск скрипта с командами

    shift_windows right
    

    и: shift_windows осталось

    В первом случае окна на левом экране должны переместиться на правый экран, а во втором - наоборот.

  4. Если все работает должным образом, добавьте сценарий к двум сочетаниям клавиш: выберите: "Системные настройки" > "Клавиатура" > "Ярлыки" > "Пользовательские ярлыки". Нажмите "+" и добавьте команды, как описано выше.

Сценарий

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

vec = sys.argv[1]

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

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

def get_shiftleft(xr_output):
    lines = [l for l in xr_output.splitlines() if  "+0" in l and not "+0+0" in l][0].split()
    return -int([it for it in lines if "x" in it][0].split("x")[0])

def shift_windows():
    xr_output = get("xrandr")
    shift_r = get_shiftright(xr_output)
    shift_l = get_shiftleft(xr_output)
    w_data = [l.split() for l in get("wmctrl -lG").splitlines()]
    for w in w_data:
        props = get("xprop -id "+w[0])
        if vec == "right":
            check = (0 < int(w[2]) < shift_r, "_TYPE_NORMAL" in props, "TYPE_DIALOG" in props).count(True)
            shift = shift_r
        if vec == "left":
            check = (shift_r-shift_l > int(w[2]) >= shift_r , "_TYPE_NORMAL" in props, "TYPE_DIALOG" in props).count(True)
            shift = -shift_r
        if check == 2:
            command = "wmctrl -ir "+w[0]+" -e 0,"+(",").join([str(int(w[2])+shift), str(int(w[3])-28), w[4], w[5]])
            subprocess.Popen(["/bin/bash", "-c", command])
shift_windows()




3. Переместить одно окно с одного экрана на другой

Хотя это не буквально ваш вопрос, всего несколько строк, вы можете перемещать все окна с одного экрана на другой, но также и одно окно (переднее) с комбинацией клавиш.

С помощью приведенного ниже сценария вы можете переместить все окна с помощью команды:

shift_windows right

или переместите одно окно командой:

shift_windows right s

Настройка практически такая же, как в приведенном выше сценарии (не забудьте установить wmctrl)

Сценарий

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

vec = sys.argv[1]
try:
    n = sys.argv[2]
except IndexError:
    n = "a"

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

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

def get_shiftleft(xr_output):
    lines = [l for l in xr_output.splitlines() if  "+0" in l and not "+0+0" in l][0].split()
    return -int([it for it in lines if "x" in it][0].split("x")[0])

def shift_windows():
    xr_output = get("xrandr")
    shift_r = get_shiftright(xr_output)
    shift_l = get_shiftleft(xr_output)
    w_data = [l.split() for l in get("wmctrl -lG").splitlines()]
    if n == "s":
        frontmost = [l for l in get("xprop -root").splitlines() if "_NET_ACTIVE_WINDOW(WINDOW)" in l][0].split()[-1]
        frontmost = frontmost[:2]+"0"+frontmost[2:]
        w_data = [l for l in w_data if frontmost in l]
    for w in w_data:
        props = get("xprop -id "+w[0])
        if vec == "right":
            check = (0 < int(w[2]) < shift_r, "_TYPE_NORMAL" in props, "TYPE_DIALOG" in props).count(True)
            shift = shift_r
        if vec == "left":
            check = (shift_r-shift_l > int(w[2]) >= shift_r , "_TYPE_NORMAL" in props, "TYPE_DIALOG" in props).count(True)
            shift = -shift_r
        if check == 2:
            command = "wmctrl -ir "+w[0]+" -e 0,"+(",").join([str(int(w[2])+shift), str(int(w[3])-28), w[4], w[5]])
            subprocess.Popen(["/bin/bash", "-c", command])
shift_windows()
Другие вопросы по тегам