web-dev-qa-db-fra.com

Ubuntu 14.10 Aero snap dans une configuration horizontale à deux écrans?

J'ai réussi à obtenir Aero snap à gauche et à droite fonctionnant dans metacity Ubuntu 14.1 et maintenant je voudrais trouver les commandes winctrl correctes pour que je puisse imiter le même effet sur deux configuration d'écran, où les deux écrans sont placés horizontalement l'un à côté de l'autre comme dans l'image ci-dessous. Je veux que cela fonctionne sur Metacity (GNOME classic), je ne suis pas du tout disposé à passer à d'autres gestionnaires de fenêtres, car je sais que certains d'entre eux ont déjà ces capacités intégrées. C'est donc une question pour essayer de trouver une réponse pour l'environnement classique Metacity GNOME en particulier:

enter image description here

Ce que je veux, c'est étendre mes commandes winctrl actuelles. Ils fonctionnent actuellement en utilisant jusqu'à la moitié de la largeur totale de l'écran à gauche ou à droite de la longueur totale de l'écran. Taper Super_L+left fera en sorte que la fenêtre active utilise la moitié gauche, et en tapant Super_L+right fera en sorte que la fenêtre active utilise la moitié droite du total des pixels horizontaux.

[hpenvy15 ~] $ cat > ~/bin/left.sh
#!/bin/bash
sleep 0.1 && wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz && wmctrl -r :ACTIVE: -e 0,0,0,`xwininfo -root | grep Width | awk '{ print (($2/2))}'`,`xwininfo -root | grep Height | awk '{ print $2 }'`
^C
[hpenvy15 ~] $ cat > ~/bin/right.sh
#!/bin/bash
sleep 0.1 && wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz && wmctrl -r :ACTIVE: -e 0,`xwininfo -root | grep Width | awk '{ print (($2/2)+5) ",0," (($2/2)) }'`,`xwininfo -root | grep Height | awk '{ print $2 }'`
^C

Dans la nouvelle configuration avec deux écrans, j'ai 1920 + 1920 pixels de large. La largeur idéale d'une fenêtre est la moitié de 1920, c'est 1920/2 = 960. Je voudrais que les nouvelles commandes left et right calculent où est la fenêtre actuellement trouvée, puis si left est tapée, pour aller au bloc de pixels le plus proche de 960 pixels , dans l'un des 4 blocs présents dans la configuration à deux écrans, 1920 + 1920, mais également au bloc le plus proche de 960 de large dans la configuration à un écran 1920. Un diagramme est illustré ci-dessous:

Il s'agit de la configuration lorsque j'ai l'écran externe en 1 et 2 et l'écran du portable en 3 et 4. Actuellement, en cliquant sur Super_L+left déplacerait la fenêtre vers la moitié gauche de TotalWidth/2 de l'écran, qui serait trop grande pour aller à 1 + 2.

Je voudrais que la première commande left la déplace vers le volet 3, puis la commande left suivante pour la déplacer vers 2, puis la suivante pour la déplacer vers 1.

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

C'est la configuration quand je n'ai que l'écran du portable en deux moitiés de 960 pixels de large.

Actuellement, en cliquant sur Super_L+right déplacerait la fenêtre vers la moitié droite de TotalWidth/2 de l'écran, ce qui correspond au numéro 4.

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

C'est la sortie de wmctrl lorsque les deux écrans sont allumés:

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

Et ceci est la sortie de xrandr également lorsque les deux écrans sont allumés:

[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)
1
719016

J'ai testé le script ci-dessous sur Ubuntu (Gnome) Classic et Gnome Flashback (Metacity) 14.04. L'application "mixte" de xdotool et wmctrl était nécessaire en raison de certaines particularités que j'ai rencontrées lors de l'écriture du script pour Metacity.

La solution

Du fait que je voulais que le script:

  • déterminer quel est l'écran gauche/droite
  • calculer les résolutions des deux moniteurs
  • fonctionne également bien si les deux écrans ont des résolutions différentes (et calculent à la fois les positions et les tailles ciblées des fenêtres)
  • fonctionne bien si un deuxième écran est connecté ou non

- le script est devenu un peu plus complet que je ne l'avais prévu.

Ce qu'il fait:

Si un deuxième moniteur est connecté:
Cela fonctionne à peu près comme vous le décrivez:

  • il divise les deux écrans en quatre zones, chaque zone est la moitié de la taille de l'écran sur lequel il se trouve (comme dit, également avec des résolutions différentes)
  • l'exécuter avec l'option "gauche" ou "droite":
    • il déplace la fenêtre vers la zone à gauche/droite de la fenêtre
    • redimensionne horizontalement à la moitié de la taille de l'écran ciblé
    • maximise la fenêtre verticalement

Si aucun deuxième moniteur n'est connecté:
Cela fonctionne de la manière traditionnelle:

  • exécuté avec l'option "gauche", il maximise la fenêtre la plus en avant verticalement sur la moitié gauche de l'écran
  • exécuté avec l'option "droite", il maximise la fenêtre la plus en avant verticalement sur la moitié droite de l'écran

Comment l'utiliser

  • Installez à la fois xdotool et wmctrl:

    Sudo apt-get install wmctrl
    Sudo apt-get install xdotool
    
  • Copiez le script dans un fichier vide, enregistrez-le sous aero.py l'exécuter par la ou les commandes

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

Le 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)

Également publié sur Gist.gisthub (dernière version)

3
Jacob Vlijm