Mover janelas semimimizadas em múltiplos monitores (2 ou mais)

5

Freqüentemente, uso as teclas Ctrl + Super + Seta para mover as janelas. No entanto, com uma configuração de vários monitores, os atalhos movem apenas as janelas na tela atual.

** Exemplo da minha situação:

Eu tenho 3 monitores e tenho uma instância de Chrome aberta no meu monitor central.

  1. Quando pressiono Ctrl + Super + Seta (esquerda) a janela se divide na metade esquerda do meu monitor central.
  2. Quando repito, a janela não se move.

O que eu gostaria de ver é que, em [2.] , a janela se mova para a metade direita do monitor mais à esquerda, e assim por diante

Como eu alcanço esse comportamento?

    
por nivla12345 07.12.2015 / 21:01

1 resposta

3

Mova suas janelas semi-maximizadas por várias telas ("aero-snap")

O script abaixo faz exatamente o que você descreve. Pode ser usado em qualquer número de telas. O script é otimizado para o Unity, mas pode ser facilmente editado para caber em outros gerenciadores de janelas.

Acabou sendo um pouco mais complicado do que eu pensava, já que o script deve levar em conta que o usuário possivelmente configurou o launcher para aparecer apenas na tela mais à esquerda (ou não). As posições segmentadas (e os tamanhos das janelas segmentadas) devem ser calculadas de acordo.


Notas

  • Oscriptmoveasjanelasatravésdetodastelasconectadas,subseqüentementealternandoentreas"metades" das telas, da esquerda para a direita e vice-versa.
  • O script lê os tamanhos das telas e define o tamanho da janela para metade do tamanho da tela de acordo.
  • O script lê as configurações no inicializador (se o iniciador aparecer apenas na primeira tela ou em todas) e calcula os tamanhos das janelas de destino de acordo.
  • O script não leva em conta a opção de autohide possivelmente definida para o inicializador. A razão é que a atualização do windowsize, uma vez que o lançador se esconde ou aparece, levaria um script de segundo plano e uma outra história para codificar.
  • As janelas são movidas e redimensionadas por uma combinação dos comandos xdotool e wmctrl -. Como esses comandos podem ter algum "comportamento característico" em combinação com o Unity, há uma possibilidade de que pequenas alterações possam ser úteis em seu sistema. Eu testei em dois sistemas (bem diferentes), no entanto, funcionando bem em ambos.

O script

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

# --- set possibly wanted marge (on the right side of the window) below
marge = 0
# --- set set launcher width below (default = 65)
default_launcherwidth = 65
# ---

move = sys.argv[1]
get = lambda cmd: subprocess.check_output(
    ["/bin/bash", "-c", cmd]).decode("utf-8")

screendata = [l for l in get("xrandr").splitlines() if " connected" in l]
# get the primary screen's position
pr = [l.split() for l in screendata if "primary" in l][0]
i = pr.index("primary"); s = pr[i+1]
primary= [int(s.split("x")[0]), int(s.split("+")[-2])]
# general screen list
screendata = [
    [s for s in l.split() if s.count("+") == 2][0] for l in screendata
    ]
screendata = [
    [int(s.split("x")[0]),int(s.split("+")[-2])] for s in screendata
    ]
screendata.sort(key=lambda x: x[1]); primary = screendata.index(primary)

def launcher_size():
    launcherset = get(
        "dconf read /org/compiz/profiles/unity/plugins/unityshell/num-launchers"
        ).strip()
    l_size_0 = 65; l_size_1 = l_size_0 if launcherset == "0" else 0
    return [l_size_0, l_size_1]

def magnets(index):
    l_size = l_sizes[0] if index == primary else l_sizes[1]
    screen = screendata[index]
    screenwidth = screen[0]; shift = screen[1]
    parts = (screenwidth - l_size)/2; virtual_mid = screenwidth - parts + shift
    left_trigger = shift + l_size
    return [left_trigger, int(virtual_mid), int(parts)]

def find_screen(x_loc):
    scr_index = len([scr for scr in screendata if x_loc >= scr[1]])-1
    scr_index = scr_index if scr_index >= 0 else 0
    screen = screendata[scr_index]
    return [scr_index, screen]

def get_active():
    active = hex(int(get("xdotool getactivewindow").strip()))
    active = active[:2]+(10-len(active))*"0"+active[2:] 
    x_pos = int([l.split()[2] for l in get("wmctrl -lG").splitlines() \
                 if l.startswith(active)][0])
    return [active, x_pos]

def decide(x_loc, active):
    current_scr = find_screen(x_loc)
    triggers = magnets(current_scr[0])
    width = triggers[2]
    index = current_scr[0]
    if move == "left":
        if x_loc <= triggers[1]:
            if x_loc == triggers[0]:
                if index != 0:
                    alter = magnets(index-1) 
                    width = alter[-1]
                    target = alter[1]
                else:
                    target = triggers[0]
            else:
                target = triggers[0]
        elif x_loc > triggers[1]:
            target = triggers[1]        
    elif move == "right":
        if x_loc >= triggers[1]:
            if index != len(screendata)-1:
                alter = magnets(index+1)
                width = alter[-1]
                target = alter[0]
            else:
                target = triggers[1]
        elif x_loc < triggers[1]:
            target = triggers[1]
    subprocess.call([
        "wmctrl", "-r", ":ACTIVE:","-b", "remove,maximized_vert,maximized_horz"
        ])
    subprocess.call(["wmctrl", "-ir", active, "-e", "0,"+str(target)+",400,"+\
                      str(int(width)-marge)+",200"])
    subprocess.call([
        "wmctrl", "-ir", active, "-b", "toggle,maximized_vert"
        ])

l_sizes = launcher_size()
w_data = get_active()
active = w_data[0]
x_loc = w_data[1]

decide(x_loc, active)

Como usar

  • O scrpt precisa dos dois wmctrl e xdotool :

    sudo apt-get instal xdotool wmctrl
    
  • Copie o script em um arquivo vazio, salve-o como move_window.py

  • Teste- execute o script a partir de uma janela de terminal (repetidamente) pelo comando:

    python3 /path/to/move_window.py right
    

    que deve mover a janela pelas telas para o computador e:

    python3 /path/to/move_window.py left
    

    que deve mover a janela pelas telas para a esquerda.

  • Se tudo funcionar bem, adicione os dois comandos às teclas de atalho: escolha: Configurações do sistema > "Teclado" > "Atalhos" > "Atalhos personalizados". Clique no botão "+" e adicione os comandos a duas teclas de atalho de sua escolha.

Notas importantes

  1. O lançador width está definido como 65px (correspondendo ao tamanho do ícone 48px + 17px borders, que é o padrão). Se a largura do conjunto for diferente, ela deve ser configurada corretamente no cabeçalho do script, conforme indicado na seção:

    # --- set set launcher width below (default = 65)
    default_launcherwidth = 65
    # ---
    
  2. Na parte superior do script, há ainda uma linha:

    marge = 0
    

    que define a margem vazia no lado direito da tela movida. Altere-o se você gostar de outro valor.

por Jacob Vlijm 14.12.2015 / 15:46