Ubuntu 14.10 Aero snap na configuração horizontal de duas telas?

1

Eu consegui fazer com que o Aero se encaixasse à esquerda e à direita trabalhando no metacity Ubuntu 14.10 e agora eu gostaria de criar os comandos winctrl corretos para que eu possa imitar o mesmo efeito em uma configuração de duas telas, onde as duas telas são colocadas horizontalmente uma ao lado da outra, como na imagem abaixo. Eu quero que isso funcione no Metacity (GNOME classic), eu não estou disposto a mudar para outros gerenciadores de janelas, já que eu sei que alguns deles já possuem esses recursos embutidos. Então, essa é uma pergunta para tentar encontrar uma resposta para o ambiente clássico do Metacity GNOME especificamente:

Oqueeuqueroéestendermeuscomandoswinctrlatuais.Elesatualmentetrabalhamusandometadedalarguratotaldatelaàesquerdaouàdireitadocomprimentototaldatela.DigitarSuper_L+leftfarácomqueajanelaativauseametadeesquerdaedigitarSuper_L+rightfarácomqueajanelaativauseotamanhodametadedireitadototaldepixelshorizontais.

[hpenvy15~]$cat>~/bin/left.sh#!/bin/bashsleep0.1&&wmctrl-r:ACTIVE:-bremove,maximized_vert,maximized_horz&&wmctrl-r:ACTIVE:-e0,0,0,'xwininfo-root|grepWidth|awk'{print(($2/2))}'','xwininfo-root|grepHeight|awk'{print$2}''^C[hpenvy15~]$cat>~/bin/right.sh#!/bin/bashsleep0.1&&wmctrl-r:ACTIVE:-bremove,maximized_vert,maximized_horz&&wmctrl-r:ACTIVE:-e0,'xwininfo-root|grepWidth|awk'{print(($2/2)+5)",0," (($2/2)) }'','xwininfo -root | grep Height | awk '{ print $2 }''
^C

Na nova configuração com duas telas, tenho 1920 + 1920 pixels de largura. A largura ideal de uma janela é metade de 1920, isto é 1920/2 = 960. Eu gostaria que os novos comandos left e right calculassem onde está a janela atualmente encontrada, então se left for digitado, para ir para o bloco de 960 pixels mais próximo, em qualquer um dos 4 blocos presentes em as duas telas, a configuração 1920 + 1920, mas também o bloco 960 de largura na configuração 1920 de uma tela. Um diagrama é mostrado abaixo:

Esta é a configuração quando eu tenho a tela externa em 1 e 2, e a tela do laptop em 3 e 4. Atualmente, clicando em Super_L+left iria mover a janela para o TotalWidth / 2 metade esquerda da tela, que seria muito grande, indo para 1 + 2.

Eu gostaria que o primeiro comando left fosse movido para o painel 3, depois o próximo comando left para movê-lo para 2, depois o próximo para movê-lo para 1.

   +-------------------++-------------------++-------------------++-------------------+
   |                   ||                   ||                   || +------------+    |
   |                   ||                   ||                   || |            |    |
   |                   ||                   ||           <-------++-+            |    |
   |                   ||                   ||                   || |            |    |
   |         1         ||         2         ||         3         || |       4    |    |
   |                   ||                   ||                   || |            |    |
   |                   ||                   ||                   || +------------+    |
   |                   ||                   ||                   ||                   |
   |                   ||                   ||                   ||                   |
   +-------------------++-------------------++-------------------++-------------------+

Esta é a configuração quando tenho apenas a tela do laptop em duas metades de 960 pixels de largura.

Atualmente, clicar em Super_L+right moveria a janela para o TotalWidth / 2 metade direita da tela, que corresponde ao número 4.

   +-------------------++-------------------+
   | +------------+    ||                   |
   | |            |    ||                   |
   | |            |    ||                   |
   | |            |----++--->               |
   | |       3    |    ||         4         |
   | |            |    ||                   |
   | |            |    ||                   |
   | +------------+    ||                   |
   |                   ||                   |
   +-------------------++-------------------+

Esta é a saída de wmctrl quando as duas telas estão ativadas:

wmctrl -d
0  * DG: 3840x1080  VP: 0,0  WA: 0,0 3840x1080  Workspace 1
1  - DG: 3840x1080  VP: N/A  WA: 0,0 3840x1080  Workspace 2
2  - DG: 3840x1080  VP: N/A  WA: 0,0 3840x1080  Workspace 3
3  - DG: 3840x1080  VP: N/A  WA: 0,0 3840x1080  Workspace 4

E esta é a saída de xrandr também quando as duas telas estão ativadas:

[hpenvy15 ~] $ xrandr
Screen 0: minimum 8 x 8, current 3840 x 1080, maximum 32767 x 32767
eDP1 connected primary 1920x1080+1920+0 (normal left inverted right x axis y axis) 344mm x 193mm
   1920x1080      60.1*+   59.9     40.0  
   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  
VGA1 disconnected (normal left inverted right x axis y axis)
HDMI1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 521mm x 293mm
   1920x1080      60.0*+   50.0     59.9     30.0     25.0     24.0     30.0     24.0  
   1920x1080i     60.1     50.0     60.0  
   1680x1050      59.9  
   1600x900       60.0  
   1280x1024      75.0     60.0  
   1440x900       59.9  
   1366x768       59.8  
   1280x800       59.9  
   1152x864       75.0  
   1280x720       60.0     50.0     59.9  
   1440x576i      50.1  
   1024x768       75.1     70.1     60.0  
   1440x480i      60.1     60.1  
   832x624        74.6  
   800x600        72.2     75.0     60.3  
   720x576        50.0  
   720x480        60.0     59.9  
   640x480        75.0     72.8     66.7     60.0     59.9  
   720x400        70.1  
VIRTUAL1 disconnected (normal left inverted right x axis y axis)
    
por 719016 04.01.2015 / 13:16

1 resposta

3

Eu testei o script abaixo no Ubuntu (Gnome) Classic e no Gnome Flashback (Metacity) 14.04. O aplicativo "misto" de xdotool e wmctrl foi necessário devido a algumas peculiaridades que tive ao escrever o script do Metacity.

A solução

Como resultado do fato de que eu queria que o script:

  • determine qual é a tela esquerda / direita
  • calcule as resoluções de ambos os monitores
  • também funciona bem se as duas telas tiverem resoluções diferentes (e calcular as posições e os tamanhos de destino das janelas)
  • funciona bem se uma segunda tela estiver conectada ou não

- o roteiro ficou um pouco mais extenso do que previ.

O que faz:

Se um segundo monitor estiver conectado:
Funciona basicamente como você descreve:

  • divide as duas telas em quatro áreas, cada área tem metade do tamanho da tela em que está localizada (como foi dito, também com diferentes resoluções)
  • executá-lo com a opção "left" ou "right":
    • move a janela para a área à esquerda / direita da janela
    • redimensiona na horizontal para metade do tamanho da tela segmentada
    • maximiza a janela verticalmente

Se nenhum segundo monitor estiver conectado:
Funciona da maneira tradicional:

  • executado com a opção "left", maximiza a janela mais frontal verticalmente na metade esquerda da tela
  • executado com a opção "right", maximiza a janela mais frontal verticalmente na metade direita da tela

Como usar

  • Instale os dois xdotool e wmctrl :

    sudo apt-get install wmctrl
    sudo apt-get install xdotool
    
  • Copie o script em um arquivo vazio, salve-o como aero.py , execute-o pelo (s) comando (s)

    python3 /path/to/aero.py left
    python3 /path/to/aero.py right
    

O script

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

move = sys.argv[1]

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

# screen resolutions ("raw")  
wds = [s for s in get("xrandr").split() if s.endswith("+0")]
# x-res left/right)
left = [scr.split("x")[0] for scr in wds if scr.endswith("+0+0")]
right = [scr.split("x")[0] for scr in wds if not scr.endswith("+0+0")]
# x-positions areas
left_pos = [0, int(int(left[0])/2), int(left[0])]
right_pos = [int(int(left[0])+int(right[0])/2)] if len(right) != 0 else []
x_positions = left_pos+right_pos
# frontmost window pos
frontmost =get("printf 0x%x "+get("xdotool getwindowfocus").strip())
frontmost = frontmost[:2]+"0"+frontmost[2:]
f_data = [l.split() for l in get("wmctrl -lG").splitlines() if frontmost in l][0][:6]
curr_pos = int(f_data[2])
area = len([x for x in x_positions if x <= curr_pos])
if move == "left":
    i = area-2; target_pos = x_positions[i] if i >= 0 else 0 
elif move == "right":
    i = area; target_pos = x_positions[area] if area < len(x_positions) else x_positions[-1]
if i >= 2:
    perc = int((100*(x_positions[-1]-x_positions[-2])/sum([int(it) for it in left+right])))
else:
    perc = int((100*(x_positions[1]-x_positions[0])/sum([int(it) for it in left+right])))
# execute actions
cmd1 = "wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz"
cmd2 = "wmctrl -ir "+f_data[0]+" -e 0,"+str(target_pos)+","+"30,300,300"
cmd3 = "xdotool windowsize $(xdotool getactivewindow) "+str(perc)+"% 100%"
for cmd in [cmd1, cmd2, cmd3]:
    execute(cmd)

Também postado em gist.gisthub (versão mais recente)

    
por Jacob Vlijm 10.01.2015 / 11:15