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:
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)
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.
Du fait que je voulais que le script:
- le script est devenu un peu plus complet que je ne l'avais prévu.
Si un deuxième moniteur est connecté:
Cela fonctionne à peu près comme vous le décrivez:
Si aucun deuxième moniteur n'est connecté:
Cela fonctionne de la manière traditionnelle:
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
#!/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)